c++ - std::enable_shared_from_this:是否允许在析构函数中调用 shared_from_this()?

标签 c++ c++11 destructor shared-ptr weak-ptr

#include <memory>
#include <iostream>

struct A : public std::enable_shared_from_this<A>
{
    ~A()
    {
        auto this_ptr = shared_from_this(); // std::bad_weak_ptr exception here. 
        std::cout << "this: " << this_ptr;
    }
};

int main()
{
    auto a = std::make_shared<A>();
    a.reset();
    return 0;
}

我在调用 shared_from_this() 时遇到 std::bad_weak_ptr 异常。是设计使然吗?是的,这可能很危险,因为在析构函数返回后无法使用此指针,但我看不出为什么在技术上不可能在这里获取指针的原因,因为共享指针对象显然仍然存在并且可以用过的。除了编写我自己的 enable_shared_from_this 模拟(我宁愿不这样做)之外,有什么办法可以避免这种情况?

最佳答案

I don't see a reason why it would be technically impossible to get the pointer here, since the shared pointer object obviously still exists and can be used.

有一个很好的技术原因说明这是不可能的。

shared_ptr可能存在,但是 A 的引用计数对象已达到零,这就是运行析构函数的原因。一旦引用计数达到零,它就不能再增加(否则你可能会得到一个 shared_ptr,它指的是一个正在运行其析构函数或已经被销毁的对象)。

调用 shared_from_this()尝试增加引用计数并返回 shared_ptr与当前所有者共享所有权,但您无法将计数器从零增加到一,因此失败。

这个非常特殊的情况下(在对象的析构函数中)你知道对象还没有被完全销毁,但是enable_shared_from_this<A>无法知道谁在调用 shared_from_this()函数,所以不知道它是发生在这个非常特殊的情况中,还是发生在对象析构函数之外的其他代码片段中(例如,在另一个将继续执行析构函数的线程中)。

如果你能以某种方式让它适用于这个特定的案例,你就会得到一个 shared_ptr<A>指的是当前正在销毁的对象,你可以给它 shared_ptr存储到析构函数之外的东西以备后用。这将允许另一段代码访问悬空的 shared_ptr。 , 在对象被销毁之后。这将是 shared_ptr 中的一个大洞和 weak_ptr类型系统。

关于c++ - std::enable_shared_from_this:是否允许在析构函数中调用 shared_from_this()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28338978/

相关文章:

c++ - CMake + Qt + GTest 文件链接

c++ - CPU如何找到变量的位置

c++11 - 完美转发,可变参数模板,initializer_list - 一起

c++ - List的析构函数不能删除最后一个节点

c++ - 使用复制构造函数后 SDL 纹理不渲染

java - 如何构造一个包含多种数据类型值的字节数组?

c++ - Cmake 将参数解析成代码

c++ - 声明后初始化 C++ 模板类

c++ - 为什么析构函数被调用两次而构造函数只被调用一次?

c++ - 我需要在这个类的析构函数中写什么吗?