c++ - 这个技巧是否会使在构造函数 'just work' 中调用 shared_from_this() 变得危险?

标签 c++ constructor this shared-ptr

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_sharedshared_pointer<T>(new T)无法在 T 之前完成构造函数已退出。

警告:该对象未完全形成,因此您不能合法调用任何虚拟方法(惩罚为 Undefined Behaviour)。


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

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

--> 另见 The Pit Of Success

关于c++ - 这个技巧是否会使在构造函数 'just work' 中调用 shared_from_this() 变得危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33069674/

相关文章:

javascript - 如何从子组件更改父状态?

javascript 类实例处理事件不一致 - this/范围界定困惑

javascript - JS如何避免使用 "this"

c# - 如何禁用特定的 usb 端口 com2 c# 64 位

exception-handling - 将异常处理放在构造函数中是一种好习惯吗?

python - 如何在 Python 单元测试中 stub time.sleep()

java - 如何通过调用构造函数获取二维数组中列大小的长度?

c++ - 为什么bernoulli_distribution::param_type 的构造函数是显式的?

c++ unordered_set with shared_ptr 搜索原始指针

c++ - 对象数组融合的通用函数