当前位置:  开发笔记 > 编程语言 > 正文

对象dtor中的`weak_ptr :: expired`行为

如何解决《对象dtor中的`weak_ptr::expired`行为》经验,为你挑选了2个好方法。

请考虑以下代码:

#include 
#include 
using namespace std;

class T;

std::weak_ptr 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();
        wptr = ptr;
        std::cout << (wptr.expired() ? "expired" : "not expired") << std::endl;
    }
    return 0;
}

在这段代码中,我试图找出weak_ptrs在对象销毁阶段是否过期.看来是这样.输出是:

not expired
in dtor
expired

我用gcc-5.1和ideone.

现在,我有另一个问题.我找不到任何文档说明这是标准行为.难道是保证这样的工作方式,始终



1> Barry..:

现在,我有另一个问题.我找不到任何文档说明这是标准行为.难道是保证这样的工作方式,始终

实际上,正如LWG第2751号提出的那样,它在标准中没有明确规定.

C++ 14标准不包含任何语言,该语言保证由a运行的删除器shared_ptr将所有关联的weak_ptr实例视为已过期.例如,标准似乎不保证以下代码段中的断言不会触发:

std::weak_ptr weak;
std::shared_ptr strong{
  new Foo,
  [&weak] (Foo* f) {
    assert(weak.expired());
    delete f;
  },
};

weak = strong;
strong.reset();

似乎很清楚,意图是关联的weak_ptrs已过期,因为否则shared_ptr删除者可以恢复对正被删除的对象的引用.

建议修复:23.11.3.2 [util.smartptr.shared.dest]应指定use_count()在调用删除器或调用之前对析构函数引起的减少进行排序delete p.

~shared_ptr()上面链接的当前措辞仅表示调用删除器,非规范性说明共享所有权的实例数量减少.

虽然意图可能是weak.expired()在调用删除器时,依赖于此是有问题的.shared_ptr确切地说,它被摧毁之后不再拥有所有权是真的是合理的 - 破坏期间询问这个问题有点奇怪.



2> Petar Velev..:

像这样使用make_shared将使用您提供的默认构造函数创建一个对象.

template< class T, class... Args >
shared_ptr make_shared( Args&&... args );

构造一个T类型的对象,并将其包装在一个std::shared_ptr using args中作为T的构造函数的参数列表.该对象就像表达式一样构造(std :: make_shared)

在主要的匿名范围之后.共享的ptr将被删除.

当发生以下任一情况时,对象将被销毁并释放其内存:

拥有该对象的最后剩余的shared_ptr被销毁; (std :: shared_ptr)

.

shared_ptr的析构函数减少控制块的共享所有者的数量.如果该计数器达到零,则控制块将调用托管对象的析构函数.在std :: weak_ptr计数器也达到零之前,控制块不会解除分配.std :: shared_ptr实施说明

这意味着您的对象将在最后一个共享ptr的破坏开始后调用其析构函数.输出:

not expired
in dtor
expired

是预期的行为.

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有