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

C++ shared_ptr循环引用疑问:Com持有Sup实例为何未触发循环引用

shared_ptr 无循环引用原因分析

循环引用的前提条件

shared_ptr 产生循环引用必须满足核心前提:

  • 至少两个对象互相持有对方的 shared_ptr 所有权
  • 双方的引用计数都因为对方的持有,无法降低到0,导致所有关联对象都无法触发析构回收

代码运行全流程拆解

我们逐行跟踪执行过程和引用计数变化即可清晰理解:

  1. 执行 auto sup = std::make_shared<Sup>(1);
    • 生成 id 为1的 Sup 对象,Sup 引用计数为1(仅栈变量 sup 持有)
    • 输出 ***CS: 1
  2. 执行 auto com = std::make_shared<Com>(1, sup);
    • 生成 id 为1的 Com 对象,Com 内部成员 supPtr_ 拷贝 sup,Sup 引用计数升至2
    • Com 引用计数为1(仅栈变量 com 持有)
    • 输出 ***ConstrCom: 1
  3. 执行创建 com2、com3 的逻辑
    • 每创建一个 Com 对象,Sup 的引用计数各加1,完成创建后 Sup 引用计数为4(栈变量sup + 3个Com的supPtr_)
    • 三个 Com 对象的引用计数各为1
  4. 执行 sup->d();
    • 进入方法后执行 auto com = std::make_shared<Com>(7, shared_from_this());:调用 shared_from_this() 拿到当前 Sup 对象的 shared_ptr,Sup 引用计数升至5;生成id为7的Com对象,输出 ***ConstrCom: 7,该 Com 的引用计数为1(仅d方法内的局部变量com持有)
    • d方法执行结束,局部变量com出作用域销毁:id为7的Com引用计数降到0,触发析构输出 ###DestrCom: 7;Com内部的supPtr_同步销毁,Sup 引用计数降回4
  5. main函数执行到return 0,栈变量按创建逆序销毁:
    • 销毁com3:Com引用计数降到0,析构输出 ###DestrCom: 3,Sup引用计数降到3
    • 销毁com2:Com引用计数降到0,析构输出 ###DestrCom: 2,Sup引用计数降到2
    • 销毁com:Com引用计数降到0,析构输出 ###DestrCom: 1,Sup引用计数降到1
    • 销毁sup:Sup引用计数降到0,析构输出 ###DestrSup 1

无循环引用的核心原因

这段代码里根本不存在双向持有所有权的情况:Sup 类本身没有任何 shared_ptr<Com> 类型的成员变量,不会长期持有任何 Com 对象的所有权;d方法内创建的Com对象是局部变量,出作用域就直接销毁,不会被Sup保留。
如果修改代码,给Sup类增加shared_ptr<Com> com_成员,并且在d方法中将创建的Com对象赋值给com_,才会形成“Sup持有Com、Com持有Sup”的双向持有关系,触发循环引用。

内容的提问来源于stack exchange,提问作者Dean Marek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:48:03