直接在构造函数中调用 shared_from_this() 会崩溃,因为 enable_shared_from_this 依赖对象已被 shared_ptr 管理,而构造函数中该条件尚未满足,导致抛出 std::bad_weak_ptr 异常。

为什么直接在构造函数里调用 shared_from_this() 会崩溃
因为 enable_shared_from_this 本身不持有引用,它只依赖外部已存在的 std::shared_ptr 来“借”出新的副本。如果对象还没被任何 std::shared_ptr 管理(比如刚 new 出来、或在构造函数中),shared_from_this() 就会抛 std::bad_weak_ptr 异常或触发未定义行为。
常见错误现象:terminate called after throwing an instance of 'std::bad_weak_ptr',尤其在类的构造函数、初始化列表、或裸指针转 shared_ptr 前就调用时。
- 必须确保该对象**已经由某个
std::shared_ptr拥有**,且这个shared_ptr的生命周期覆盖调用点 - 不能用
new MyClass()后再传给shared_ptr构造——这会导致内部weak_ptr未初始化;应改用std::make_shared<myclass>()</myclass> -
enable_shared_from_this是空基类,不增加对象大小,但要求继承方式为 public
正确写法:继承 + make_shared + shared_from_this()
最安全、最常用的模式是让类 public 继承 std::enable_shared_from_this<t></t>,并**只通过 std::make_shared 创建实例**。
class Node : public std::enable_shared_from_this<Node> {
public:
std::shared_ptr<Node> get_self() {
return shared_from_this(); // ✅ 安全
}
<pre class="brush:php;toolbar:false;">void schedule_callback() {
auto self = shared_from_this(); // ✅ 在成员函数内调用没问题
some_async_api([self]() { /* use self */ });
}};
立即学习“C++免费学习笔记(深入)”;
关键点:
- 继承声明必须是
public std::enable_shared_from_this<node></node>,否则shared_from_this()不可访问 - 必须用
std::make_shared<node>()</node>构造,不能用std::shared_ptr<node>(new Node)</node>——后者不会初始化内部weak_ptr -
shared_from_this()返回的是新拷贝的shared_ptr,引用计数+1,和原始shared_ptr共享所有权
不能用 shared_from_this() 的场景及替代方案
有些时候你确实需要在非成员上下文(比如回调、静态工厂、或 legacy 接口)里拿到 shared_ptr,但又无法保证已有外部管理。这时 shared_from_this() 不适用,强行用会 crash。
常见误用场景:
- 从 C 回调函数里反向调用 C++ 对象,并试图“自救”成
shared_ptr - 类内部缓存一个裸指针(
this),之后某时刻想转成shared_ptr - 多线程中,对象可能已被销毁,但你还想调用
shared_from_this()
可行替代:
- 把
shared_ptr显式传入回调(例如:绑定[ptr = shared_from_this()](){ ... }) - 用
weak_ptr缓存并检查是否还存活:auto ptr = weak_self.lock(); if (ptr) { ... } - 避免裸指针持有,改为由上层统一管理生命周期(如容器持有一个
vector<shared_ptr>></shared_ptr>)
注意 shared_from_this() 的线程安全性
shared_from_this() 本身是线程安全的——它只是拷贝内部已有的 weak_ptr 并调用 lock(),但前提是:该对象的原始 shared_ptr 没有被其他线程同时析构。
换句话说,它不解决竞态,只保证自己这一步不出错。容易被忽略的点:
- 如果你在析构函数里调用
shared_from_this(),行为未定义(对象正在销毁,内部weak_ptr可能已失效) - 多个线程同时调用
shared_from_this()没问题;但若一个线程正销毁最后一个shared_ptr,另一个线程刚好调用,结果可能是返回空shared_ptr(lock()失败) - 不要把它当作“保活”机制:它不延长生命周期,只是获取当前有效引用的副本
真正要保活,得靠外部持有 shared_ptr,或者用 weak_ptr 配合 lock() 判断后再使用。


















