对象dtor中的weak_ptr :: expired行为 [英] `weak_ptr::expired` behavior in the dtor of the object
问题描述
考虑以下代码:
#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
在对象销毁阶段是否已过期.好像是输出为:
In this code, I was trying to find out if weak_ptr
s are expired in the objects destruction phase. It seems so. The output is:
not expired
in dtor
expired
我将gcc-5.1与 ideone 一起使用.
I used gcc-5.1 with 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问题2751 提出的标准中对它的指定没有充分说明.
No. Indeed, it's underspecified in the standard, as raised by LWG issue 2751.
C ++ 14标准不包含任何保证由
shared_ptr
运行的删除程序将所有已关联的weak_ptr
实例视为已过期的语言.例如,该标准似乎无法保证以下代码段中的断言不会触发:
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();
似乎很明显,目的是关联的weak_ptr
已过期,否则,shared_ptr
删除程序可以恢复对正在删除的对象的引用.
It seems clear that the intent is that associated weak_ptr
s are expired, because otherwise shared_ptr
deleters could resurrect a reference to an object that is being deleted.
建议的修复程序:23.11.3.2 [util.smartptr.shared.dest] 应该指定由析构函数导致的use_count()
减少是在调用删除器或调用delete p
之前排序的.
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 to delete p
.
上面链接的~shared_ptr()
的当前措辞只是说明删除程序已被调用,但非规范性的说明共享所有权的实例数会减少.
The current wording for ~shared_ptr()
as linked above simply states that the deleter is invoked, with a non-normative note that the number of instances that share ownership is decreased.
尽管意图是在调用删除程序时weak.expired()
,但是依靠它还是有问题的.只有自信地声明shared_ptr
在被销毁后不再拥有所有权,这才是合理的-询问在销毁期间的问题有点奇怪.
While the intent is probably that weak.expired()
when the deleter is called, it's questionable to rely on this. It's really only reasonable to state with confidence that the shared_ptr
no longer shares ownership after it's been destroyed - asking that question during destruction is a bit odd.
这篇关于对象dtor中的weak_ptr :: expired行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!