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

2024-04-06

考虑以下代码:

#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_ptrs 在对象销毁阶段过期。看来是这样。输出是:

not expired
in dtor
expired

我使用 gcc-5.1ideone http://ideone.com/ZSKXC2.

现在,我有另一个问题。我找不到任何文档说明这是标准行为。这样能保证工作吗always?


现在,我有另一个问题。我找不到任何文档说明这是标准行为。这样能保证工作吗always?

不。事实上,正如提出的那样,标准中对此没有明确规定LWG 问题 2751 https://cplusplus.github.io/LWG/issue2751.

C++14 标准不包含任何语言可以保证删除器由shared_ptr将看到所有关联的weak_ptr实例已过期。例如,该标准似乎不能保证以下代码片段中的断言不会触发:

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_ptrs 已过期,因为否则shared_ptr删除器可以恢复对正在删除的对象的引用。

建议修复:23.11.3.2[util.smartptr.shared.dest] http://eel.is/c++draft/util.smartptr.shared.dest应明确指出减少use_count()由析构函数引起的在调用删除器或调用之前排序delete p.

目前的措辞为~shared_ptr()如上面链接的那样,仅说明删除器被调用,并带有一个非规范性注释,表明共享所有权的实例数量减少了。

虽然意图可能是这样的weak.expired()当删除器被调用时,依赖它是有问题的。只有充满信心地声明,这才是真正合理的shared_ptr不再分享所有权after它已被摧毁 - 问这个问题during破坏有点奇怪。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对象 dtor 中的 `weak_ptr::expired` 行为 的相关文章

随机推荐