对象dtor中的weak_ptr :: expired行为 [英] `weak_ptr::expired` behavior in the dtor of the object

查看:301
本文介绍了对象dtor中的weak_ptr :: expired行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

#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_ptrs 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 associated weak_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_ptrs 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆