C++开发中什么时候需要使用shared_from_this()?
你给出的示例里已经持有外部shared_ptr<A> ptr_a的场景确实不需要调用shared_from_this(),直接传ptr_a即可。shared_from_this()的核心价值是在类的内部成员函数中,安全获取指向当前对象、和外部共享引用计数的shared_ptr实例,典型适用场景如下:
- 异步回调场景
类的成员函数发起异步任务时,需要将当前对象的shared_ptr绑定到回调函数中,保证回调执行时对象还未被析构。此时成员函数内部无法拿到外部持有的shared_ptr,只能通过shared_from_this()生成。
示例代码:#include <future> class A : public std::enable_shared_from_this<A> { public: void async_task() { // 把当前对象的shared_ptr绑定到异步回调,避免回调执行时对象被释放 std::async(std::launch::async, [self = shared_from_this()]() { // 回调逻辑,访问self的成员 self->a = 10; // 其他操作 }); } private: int a = 0; }; - 观察者/注册类场景
当前类作为观察者需要注册到全局/其他组件的观察者列表时,需要传递自身的shared_ptr保证注册期间对象存活,此时在注册成员函数中只能通过shared_from_this()生成实例传递。 - 避免双重释放风险
如果在类内部直接用std::shared_ptr<A>(this)返回指向自身的智能指针,会生成独立的引用计数控制块,和外部持有的shared_ptr计数不共享,两个计数归零时会重复析构同一个对象,触发未定义行为。shared_from_this()会复用外部shared_ptr的控制块,只会维护一套引用计数,完全规避该问题。
注意事项
使用shared_from_this()前必须保证已经存在一个持有当前对象的shared_ptr实例,否则会抛出异常(C++17前为未定义行为)。通常建议将类的构造函数设为私有,对外提供静态工厂方法返回shared_ptr实例,从根源避免错误使用:
class A : public std::enable_shared_from_this<A> { public: static std::shared_ptr<A> create() { return std::shared_ptr<A>(new A()); } private: // 构造函数私有,禁止外部直接创建对象,避免栈上实例、裸指针new的情况 A() = default; int a = 0; };
内容的提问来源于stack exchange,提问作者Yacheng Liu
相关产品推荐
相关产品推荐

