考虑以下代码:
#include <iostream>
#include <memory>
using namespace std;
class T;
std::weak_ptr<T> wptr;
class T
{
public:
T() { }
~T() {
std::cout << "in dtor" << std::endl;
std::cout << (wptr.expired() ? "expired" : "not expired") << std::endl;
}
};
int main() {
{
auto ptr = std::make_shared<T>();
wptr = ptr;
std::cout << (wptr.expired() ? "expired" : "not expired") << std::endl;
}
return 0;
}
在这段代码中,我试图找出 weak_ptr
是否在对象销毁阶段过期。似乎是这样。输出是:
not expired
in dtor
expired
我使用 gcc-5.1 和 ideone .
现在,我有另一个问题。我找不到任何说明这是标准行为的文档。是否保证以这种方式工作,总是?
最佳答案
Now, I have another problem. I couldn't find any documentation stating that this is the standard behavior. Is it guaranteed to work this way, always?
没有。事实上,正如 LWG issue 2751 所提出的,它在标准中没有被详细说明。 .
The C++14 standard contains no language that guarantees the deleter run by a
shared_ptr
will see all associatedweak_ptr
instances as expired. For example, the standard doesn't appear to guarantee that the assertion in the following snippet won't fire:std::weak_ptr<Foo> weak; std::shared_ptr<Foo> strong{ new Foo, [&weak] (Foo* f) { assert(weak.expired()); delete f; }, }; weak = strong; strong.reset();
It seems clear that the intent is that associated
weak_ptr
s are expired, because otherwiseshared_ptr
deleters could resurrect a reference to an object that is being deleted.Suggested fix: 23.11.3.2 [util.smartptr.shared.dest] should specify that the decrease in
use_count()
caused by the destructor is sequenced before the call to the deleter or the call todelete p
.
上面链接的 ~shared_ptr()
的当前措辞只是说明调用了删除器,并带有非规范性说明,即共享所有权的实例数量减少了。
虽然调用删除器时的意图可能是 weak.expired()
,但依赖它是有问题的。只有在shared_ptr
被销毁后 不再共享所有权的自信声明才是合理的 - 问这个问题在 销毁过程中有点奇怪.
关于c++ - `weak_ptr::expired` 对象 dtor 中的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41851520/