当我从std::enable_shared_from_this
继承但创建一个unique_ptr时,weak_ptr
内的std::enable_shared_from_this
也会被{{“移动”到shared_ptr
时进行初始化1}},还是通过move构造函数?
例如,下面的代码将发生什么:
std::move
答案 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
的指针启用p
和p
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
。