C++使用shared_from_this后对象无法析构问题求解
问题根因分析
首先纠正理解偏差:shared_from_this()的返回值是std::shared_ptr<Name>,并非弱指针。你看到的实现逻辑描述是指它内部通过enable_shared_from_this持有的私有weak_ptr成员构造出一个新的shared_ptr,会增加目标对象的引用计数。
你遇到的不析构问题是典型的shared_ptr循环引用:
Name类实例持有指向Another实例的shared_ptr<Another>成员,Another类实例又持有指向Name实例的shared_ptr<Name>成员。两个对象的引用计数被对方持有,当外部的shared_ptr销毁后,两个对象的引用计数都停留在1,永远无法降到0触发析构。
- 继承
enable_shared_from_this<T>的类,所有实例必须用std::shared_ptr管理生命周期,禁止创建栈实例、用裸指针接管堆实例,否则调用shared_from_this()会触发未定义行为。 - 如果存在从属类需要回指所有者类的场景,回指指针必须使用
std::weak_ptr<T>而非shared_ptr<T>,避免形成循环引用。 shared_from_this()只能在类的非静态成员函数中调用,禁止在构造函数中调用(构造时enable_shared_from_this内部的weak_ptr还未完成初始化)。
修复方案
仅需要修改Another类的成员类型即可,回指指针改用weak_ptr不增加Name对象的引用计数,不会形成循环:
struct Another { // 原shared_ptr改为weak_ptr std::weak_ptr<Name> nn; Another(shared_ptr<Name> n) : nn(n) { std::cout << "from another constructor " << n.use_count() << "\n"; } ~Another() { std::cout << "from another destructor\n"; } };
修改后运行会正常输出两个类的析构日志,内存可以正常回收。需要使用回指的Name实例时,调用weak_ptr的lock()方法临时生成shared_ptr使用即可,临时shared_ptr销毁后不会长期占用引用计数。
内容的提问来源于stack exchange,提问作者kishoredbn
相关产品推荐
相关产品推荐

