c – 这个技巧是,在构造函数中调用shared_from_this()“正常工作”,这很危险吗?

C专家的问题.

我们都知道在类构造函数中调用shared_from_this()会导致bad_weak_ptr异常,因为还没有创建实例的shared_ptr.

作为解决方法,我提出了这个诀窍:

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() {}
};

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

我没有使用’this’来访问成员变量或函数.此外,只要我使用了初始化列表,所有成员变量都已初始化.我不知道这招可能不安全.

编辑:事实证明这个技巧确实会造成不必要的副作用. shared_from_this()将指向临时的shared_ptr,如果你不小心,我的示例代码中的父子关系将会中断. enable_shared_from_this()的实现根本不允许它.谢谢,Sehe,指出我正确的方向.

最佳答案
这不危险.

记录的限制是:cppreference

Before calling shared_from_this, there should be at least one std::shared_ptr p that owns
*this

没有任何地方说它不能从构造函数内部使用/出于这个原因/.

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

警告:对象没有完全形成,所以你不能合法地调用任何虚拟方法(在Undefined Behaviour的惩罚).

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

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

– >另见The Pit Of Success

转载注明原文:c – 这个技巧是,在构造函数中调用shared_from_this()“正常工作”,这很危险吗? - 代码日志