You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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正确使用规则
  • 继承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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:45:01