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

#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,但是您不能将计数器从0增加到1,因此它会失败.

在这个非常特殊的情况下(在对象的析构函数内),你知道对象还没有完全被破坏,但是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()? - 代码日志