std :: enable_shared_from_this:是否允许在析构函数中调用shared_from_this()? [英] std::enable_shared_from_this: is it allowed to call shared_from_this() in destructor?

查看:250
本文介绍了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'm getting std::bad_weak_ptr exception when calling shared_from_this(). Is it by design? Yes, it might be dangerous as this pointer can't be used after the destructor returns, but 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. Is there any way to circumvent this, short of writing my own enable_shared_from_this analog (which I would rather not do)?

推荐答案

我看不出为什么在这里将指针从技术上讲是不可能的原因,因为共享指针对象显然仍然存在并且可以使用.

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.

有一个很好的技术原因,使之不可能.

There's a very good technical reason why it's not possible.

shared_ptr可能存在,但是A对象的引用计数已达到零,这就是运行析构函数的原因.一旦引用计数达到零,就不能再次增加它(否则,您可能会得到shared_ptr,它引用的对象要么正在运行其析构函数,要么已被破坏).

The shared_ptr might exist, but the reference count for the A object has reached zero, that's why the destructor is being run. Once the reference count reaches zero it cannot be increased again (otherwise you could get a shared_ptr that refers to an object that is either in the middle of running its destructor, or has already been destroyed).

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

Calling shared_from_this() tries to increase the reference count and return a shared_ptr that shares ownership with the current owner(s), but you can't increase the counter from zero to one, so it fails.

在这种非常特殊的情况下(在对象的析构函数内部),您知道该对象尚未完全销毁,但是enable_shared_from_this<A>无法知道谁在调用shared_from_this()函数,因此无法知道它是否发生在这种非常特殊的情况或对象的析构函数之外的其他代码段中(例如,在将继续追随析构函数的另一个线程中).

In this very specific case (inside the object's destructor) you know the object hasn't been completely destroyed yet, but enable_shared_from_this<A> has no way to know who is calling the shared_from_this() function, so can't know if it's happening in this very specific case or in some other piece of code outside the object's destructor (e.g. in another thread that will keep going after the destructor).

如果您能以某种方式使其适用于此特定情况,并且得到了一个shared_ptr<A>来引用当前正在销毁的对象,则可以将该shared_ptr分配给析构函数之外的东西,以便将其存储起来以备后用.在对象被销毁之后,这将允许其他代码段访问悬空的shared_ptr.在shared_ptrweak_ptr类型的系统中,这将是一个大漏洞.

If you could somehow make it work for this specific case and you got a shared_ptr<A> that referred to the object currently being destroyed, you could give that shared_ptr to something outside the destructor that stored it for later use. That would allow that other piece of code to access a dangling shared_ptr, after the object has been destroyed. That would be a big hole in the shared_ptr and weak_ptr type system.

这篇关于std :: enable_shared_from_this:是否允许在析构函数中调用shared_from_this()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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