不能在构造函数中调用shared_from_this(),否则抛std::bad_weak_ptr异常;必须继承std::enable_shared_from_this且对象由std::shared_ptr管理才可用。

不能直接在构造函数里调用 shared_from_this(),否则会抛 std::bad_weak_ptr 异常——这是最常踩的坑。
为什么必须继承 std::enable_shared_from_this
因为 shared_from_this() 依赖内部一个 std::weak_ptr 成员(std::enable_shared_from_this 提供),该成员只在对象被 std::make_shared 或 std::shared_ptr 构造时自动绑定。如果只是普通 new 出来,或者没继承这个基类,调用就必然失败。
- 必须显式继承:
class MyClass : public std::enable_shared_from_this<myclass></myclass> - 继承不增加对象大小(空基类优化生效)
- 模板参数必须严格匹配派生类名,写成
enable_shared_from_this<base>在派生类里调用会返回指向 Base 的指针,类型不安全
shared_from_this() 的典型使用场景
常见于需要把 this 安全转为 std::shared_ptr 并传给异步操作、回调或容器管理的场合,比如注册监听器、启动定时器、作为 lambda 捕获对象等。
- 异步回调中避免悬空指针:
timer->start([self = shared_from_this()] { self->on_timeout(); }); - 向观察者列表添加自身:
observers.push_back(shared_from_this()); - 注意:不能在析构函数里调用——此时控制块可能已失效,行为未定义
构造时机决定能否调用
只有当对象已被纳入某个 std::shared_ptr 管理后,shared_from_this() 才可用。这意味着:
立即学习“C++免费学习笔记(深入)”;
- 构造函数体内部(包括初始化列表之后)一律不可调用
- 推荐做法:用
std::make_shared<myclass>(...)</myclass>创建对象,再在后续方法中首次调用shared_from_this() - 若必须从裸指针开始,可先用
std::shared_ptr<myclass> ptr(new MyClass)</myclass>,但需确保此后不再用裸指针 delete,且仍要继承enable_shared_from_this
真正容易忽略的是:即使类继承了 std::enable_shared_from_this,只要它不是由 std::shared_ptr 管理的,shared_from_this() 就永远抛异常——这个约束不是编译期检查,而是运行期陷阱。


















