从唯一指针移动到共享指针还将初始化enable_shared_from_this

时间:2018-12-18 14:09:53

标签: c++ stl smart-pointers

当我从std::enable_shared_from_this继承但创建一个unique_ptr时,weak_ptr内的std::enable_shared_from_this也会被{{“移动”到shared_ptr时进行初始化1}},还是通过move构造函数?

例如,下面的代码将发生什么:

std::move

3 个答案:

答案 0 :(得分:4)

根据https://en.cppreference.com/w/cpp/memory/enable_shared_from_this,所有std::shared_ptr构造函数都应初始化内部弱引用,因此将std::unique_ptr移入std::shared_ptr应该可以使用shared_from_this

您必须注意,在对象归shared_from_this拥有的情况下,没人会调用std::unique_ptr,因为这是未定义的行为,或者会根据您的c ++版本而抛出std::bad_weak_ptr

答案 1 :(得分:4)

  

[util.smartptr.shared.const] / 1 在下面的构造函数定义中,为类型为shared_from_this的指针启用pp Y*表示如果Y具有明确且可访问的基类,并且是enable_shared_from_this的特化(23.11.2.5),则remove_cv_t<Y>*应隐式转换为{{ 1}},然后构造函数评估该语句:

T*
     
if (p != nullptr && p->weak_this.expired())
p->weak_this = shared_ptr<remove_cv_t<Y>>(*this, const_cast<remove_cv_t<Y>*>(p));
     

[util.smartptr.shared.const] / 29 效果: ...相当于template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);

     
shared_ptr(r.release(), r.get_deleter())
     

[util.smartptr.shared.const] / 10 效果:构造一个拥有对象template<class Y, class D> shared_ptr(Y* p, D d); 和删除器的shared_ptr对象p。如果d不是数组类型,则通过T

启用shared_from_this

是的,p确实进行了适当的初始化,以使std::shared_ptr< A > s(std::move(u));正常工作。

答案 2 :(得分:0)

正如艾伦(Alan)和伊戈尔(Igor)指出的那样,只要构建std::weak_ptr<>来容纳从shared_from_this()公开派生的对象,就可以适当地设置实现std::shared_ptr<>魔术的std::enable_shared_from_this。所以,是的,您的代码将起作用。

但是,成员方法

std::shared_ptr<A> A::getA()
{
    return shared_from_this();
}
除非对象实际上由std::shared_ptr<>管理,否则

将调用UB(在C ++ 17之前)。不幸的是,在C ++ 17之前,无法从对象(类型A)中判断该对象是否由共享指针管理,因此无法轻松阻止此UB。

由于您实际上是在使用std::unique_ptr<>来管理对象,因此,我建议不要继承自std::enable_shared_from_this