这是骗子,调用shared_from_this()在构造函数“只是工作”,危险吗? [英] Is this trick, to make calling shared_from_this() in the constructor 'just work', dangerous?

查看:1066
本文介绍了这是骗子,调用shared_from_this()在构造函数“只是工作”,危险吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++专家的问题。

Question for the C++ experts.

我们都知道在类构造函数中调用shared_from_this()会导致一个bad_weak_ptr异常,因为没有shared_ptr

We all know that calling shared_from_this() in the class constructor will result in a bad_weak_ptr exception, because no shared_ptr to the instance has been created yet.

作为一个解决方法,我想出了这个秘诀:

As a work-around for that, I came up with this trick:

class MyClass : public std::enable_shared_from_this<MyClass>
{
public:
    MyClass() {}

    MyClass( const MyClass& parent )
    {
        // Create a temporary shared pointer with a null-deleter
        // to prevent the instance from being destroyed when it
        // goes out of scope:
        auto ptr = std::shared_ptr<MyClass>( this, [](MyClass*){} );

        // We can now call shared_from_this() in the constructor:
        parent->addChild( shared_from_this() );
    }

    virtual ~MyClass() {}
};

有人认为这不安全,因为对象尚未完全形成。他是对的吗?

Someone argued that this is not safe, as the object has not yet been fully formed. Is he right about that?

我没有使用'this'来访问成员变量或函数。此外,所有成员变量已经被初始化,假设我使用初始化列表。

I'm not using 'this' to access member variables or functions. Furthermore, all member variables have already been initialized, provided I used initializer lists. I don't see how this trick could be unsafe.

编辑:事实证明,这种技巧确实会产生不想要的副作用。 shared_from_this()将指向临时 shared_ptr ,如果不小心,父子关系我的示例代码将中断。执行 enable_shared_from_this()根本不允许它。

Edit: it turns out this trick indeed creates unwanted side-effects. The shared_from_this() will point to the temporary shared_ptr and if you're not careful, the parent-child relationship in my sample code will break. The implementation of enable_shared_from_this() simply does not allow it. Thanks, Sehe, for pointing me in the right direction.

推荐答案

这不是危险的。

记录的限制是: cppreference


在调用 shared_from_this 之前,一个 std :: shared_ptr p 拥有
* this

它无法说明它不能在构造函数内使用/为此原因/.

Nowhere does it say that it can't be used from inside the constructor /for this reason/.

这只是一个典型。这是因为在正常情况下, make_shared shared_pointer< T>(new T) T 构造函数退出之前无法完成。

It's just a-typical. That's because under normal circumstances, a make_shared or shared_pointer<T>(new T) cannot complete before the T constructor has exited.

注意:对象未完全形成, em> legal 调用任何虚拟方法(违反未定义行为)。

Caveat: the object isn't fully formed so you cannot legally invoke any virtual methods (at the penalty of Undefined Behaviour).

指南由于可能使用此类别错误(例如使用 shared_ptr< T>(new T)它创建一个具有相同底层指针值的第二个shared_ptr ... oops)你应该更喜欢一个防止这种情况的设计。

Guideline Since it's possible to use this class wrong (e.g. using shared_ptr<T>(new T) which creates a second shared_ptr with the same underlying pointer value... oops) you should prefer a design that prevents this.


使用返回 shared_ptr< T> 的朋友工厂函数可能是一种方法。

Using a friend factory function that returns the shared_ptr<T> could be one approach.

- >另请参阅成功的坑

这篇关于这是骗子,调用shared_from_this()在构造函数“只是工作”,危险吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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