尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

shared_ptr的一个最大的陷阱是循环引用,如何解决循环引用

shared_ptr的一个最大的陷阱是循环引用,如何解决循环引用
📅 发布时间:2026/7/23 21:02:10

在C++中,std::shared_ptr提供了一种智能指针,用于自动管理动态分配对象的生命周期。然而,当多个shared_ptr相互引用时,如果不恰当地管理,就可能造成所谓的“循环引用”问题。循环引用指的是两个或多个shared_ptr相互持有对方的引用,从而导致它们都无法独立地减少引用计数到零,因此无法自动释放内存。

循环引用的例子

假设有两个类A和B,每个类都有一个指向对方类型的shared_ptr:

classB;// 前向声明classA{public:std::shared_ptr<B>b;};classB{public:std::shared_ptr<A>a;};

如果你这样创建对象:

std::shared_ptr<A>a(newA);std::shared_ptr<B>b(newB);a->b=b;b->a=a;

在这种情况下,每个shared_ptr都至少被对方持有一个引用,因此它们的引用计数永远不会达到零。这意味着对象a和b都不会被自动删除,导致内存泄漏。

如何解决循环引用问题

  1. 使用weak_ptr

一个常用的解决方案是使用std::weak_ptr。weak_ptr不会增加对象的引用计数,但它允许你访问由shared_ptr管理的对象。你可以将其中一个shared_ptr替换为weak_ptr来打破循环引用:

classB;// 前向声明classA{public:std::weak_ptr<B>b;// 使用 weak_ptr 替代 shared_ptr};classB{public:std::shared_ptr<A>a;// 仍然使用 shared_ptr};

创建对象时:

std::shared_ptr<A>a(newA);std::shared_ptr<B>b(newB);a->b=b;// 注意这里不需要改变b->a,因为我们已经用weak_ptr处理了循环引用的问题b->a=a;// 仍然需要设置,因为我们需要访问a对象

这样,即使a通过weak_ptr指向b,b仍然可以保持对a的强引用。当不再需要访问a时,你可以通过b->a.lock()来安全地获取shared_ptr并管理生命周期。

  1. 使用std::enable_shared_from_this

对于某些情况,如果你确实需要在对象内部保持对其他对象的强引用,可以使用std::enable_shared_from_this基类。这允许对象在其成员函数中安全地获取自己的shared_ptr:

include<memory>include<iostream>classB;// 前向声明classA:publicstd::enable_shared_from_this<A>{public:std::shared_ptr<B>b;voidsetB(std::shared_ptr<B>bPtr){b=bPtr;}// 需要手动设置b的引用,因为不能自动获取自己的shared_ptr来设置b的引用计数。通常在构造函数或初始化函数中设置。};classB:publicstd::enable_shared_from_this<B>{public:std::shared_ptr<A>a;// 使用 enable_shared_from_this 的对象可以安全地获取自己的 shared_ptr。};

在创建对象时:

autoa=std::make_shared<A>();// 自动管理生命周期的智能指针。autob=std::make_shared<B>();// 同理。a->setB(b);// 手动设置b的引用。注意这里不需要改变b->a的设置方式。b->a=a;// 仍然需要设置,因为我们需要访问a对象。但通常在构造函数或初始化函数中设置会更安全。

结论
通过使用weak_ptr或enable_shared_from_this,你可以有效地解决shared_ptr之间的循环引用问题,避免内存泄漏。选择哪种方法取决于你的具体需求和设计决策。

相关新闻

  • 2026 年平鲁口碑好的景观闸门订制厂家推荐几家,揭秘隐藏的流量密码:景观闸门如何改变你的视野? - 企业推荐官【认证】
  • 基于C2000 CLA协处理器的三相异步电机无感FOC控制实战指南
  • 抖掌柜:抖音小店一件代发密文下单,规避隐私违规风险 - 电商分享

最新新闻

  • 【仅剩47份】AI数据可视化高阶训练营内部讲义泄露版:含LLM自动生成图表Prompt库+异常模式识别热力图算法
  • Sheet-to-Doc Skill:让AI助手帮你自动生成长Word文档
  • 警惕高价引流套路!上海黄金回收真实计价逻辑全面拆解 - 日常比对手册
  • 2026 年太原代理记账公司哪家靠谱?5 家正规机构盘点,避开低价隐形消费坑 - 山西融纳集团
  • 台球三大玩法技术向深度解析:中式八球、九球、斯诺克的规则体系与策略差异
  • 杭州学校教育服务GEO城市合伙人选型推荐哪家靠谱?从7大维度拆解选型关键要素 - 小随科技

日新闻

  • 亨得利盐城维修点在哪里?手表维修保养地址指南**公示(2026年7月最新) - 亨得利官方
  • 提升.NET API安全性:Boxed.AspNetCore.Swagger认证授权最佳实践
  • 帝舵佛山**网点地址更新:2026年7月售后热线电话与服务客户指南 - 帝舵中国官方服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号