调用shared_from_this为何触发std::terminate?
问题出在哪?
你这段代码在VS2017里触发终止的核心原因很明确:你调用shared_from_this()的对象a根本没被任何std::shared_ptr托管。
std::enable_shared_from_this可不是随便用的——它的工作逻辑是:当一个对象被std::shared_ptr(或者std::make_shared)创建/接管时,这个智能指针会自动给enable_shared_from_this内部的弱引用指针赋值。只有当这个弱引用存在时,shared_from_this()才能安全生成一个指向该对象的新shared_ptr。
但你代码里的A a;是栈上的局部对象,从头到尾都没被shared_ptr管理过,shared_from_this()找不到有效的弱引用,VS的调试断言就直接触发终止了。
怎么改才对?
你要做的就是确保对象从一开始就被std::shared_ptr接管,最推荐的方式是用std::make_shared创建对象:
#include <memory> class A : public std::enable_shared_from_this<A> { public: std::shared_ptr<A> f() { return shared_from_this(); } }; int main() { // 用make_shared创建被shared_ptr管理的对象 std::shared_ptr<A> ptr1 = std::make_shared<A>(); // 现在调用f()就安全了 std::shared_ptr<A> ptr2 = ptr1->f(); // ptr1和ptr2指向同一个对象,引用计数会正确增加到2 }
如果确实需要先创建裸指针再转成shared_ptr(不推荐,容易出错),也可以这么写:
int main() { A* raw_a = new A(); std::shared_ptr<A> ptr1(raw_a); std::shared_ptr<A> ptr2 = ptr1->f(); }
但一定要记住:栈上的对象绝对不能用shared_from_this()!栈对象的生命周期由编译器控制,shared_ptr没法接管它的内存,强行这么做只会导致未定义行为。
额外注意点
- 别在类的构造函数里调用
shared_from_this(),因为此时对象还没被shared_ptr完全初始化,内部的弱引用还没设置好,同样会触发错误。 - 必须public继承
std::enable_shared_from_this,否则shared_from_this()可能无法访问基类的内部成员,导致编译或运行错误。
内容的提问来源于stack exchange,提问作者Eduard Rostomyan
相关产品推荐
相关产品推荐

