新闻中心
c++中的std::weak_ptr怎么解决循环引用问题_c++ weak_ptr避免shared_ptr循环引用
循环引用指两个对象的shared_ptr相互持有,导致引用计数无法归零而内存泄漏;weak_ptr不增加引用计数,可打破循环。

在C++中,std::shared_ptr通过引用计数管理对象生命周期,但当两个或多个对象相互持有对方的shared_ptr时,就会出现循环引用问题。这会导致对象无法被正确释放,从而引发内存泄漏。std::weak_ptr正是为了解决这个问题而设计的。
什么是循环引用?
考虑两个类A和B,它们彼此持有对方的shared_ptr:
class B; // 前向声明class A {
public:
std::shared_ptr ptr;
~A() { std::cout };
class B {
public:
std::shared_ptr ptr;
~B() { std::cout };

int main() {
auto a = std::make_shared();
auto b = std::make_shared();
a->ptr = b;
b->ptr = a; // 循环形成
}
此时,a和b的引用计数都为2。当main函数结束时,a和b离开作用域,各自引用计数减1,变为1,但由于仍存在指向它们的shared_ptr(在对方内部),析构函数不会被调用,造成内存泄漏。
weak_ptr如何打破循环
std::weak_ptr不增加引用计数,它只是“观察”一个由shared_ptr管理的对象。你可以通过lock()方法临时获取一个shared_ptr来安全访问对象,如果对象已被释放,则返回空的shared_ptr。
修改上面的例子,让其中一个类使用weak_ptr:
易标AI
告别低效手工,迎接AI标书新时代!3分钟智能生成,行业唯一具备查重功能,自动避雷废标项
135
查看详情
class B;class A {
public:
std::shared_ptr ptr;
~A() { std::cout };
class B {
public:
std::weak_ptr ptr; // 改成 weak_ptr
~B() { std::cout };
int main() {
auto a = std::make_shared();
auto b = std::make_shared();
a->ptr = b;
b->ptr = a; // 不增加引用计数
}
现在,a的引用计数为2(外部a + b.ptr.lock()),但b的引用计数只有1(外部b)。当main结束,b先被释放,然后a的引用计数变为1再变为0,最终a也被释放。析构顺序正常执行,内存得以回收。
何时使用weak_ptr
在以下场景中推荐使用weak_ptr:
- 父子关系中,子对象持有父对象的弱引用
- 缓存或监听器机制中,避免因强引用导致对象无法释放
- 回调函数中传递对象引用,防止生命周期被意外延长
- 任何可能出现双向引用的结构中,选择一方使用weak_ptr
访问weak_ptr时需注意:必须通过lock()获取shared_ptr,不能直接解引用。例如:
if (auto locked = b->ptr.lock()) {// 安全使用 locked
std::cout } else {
std::cout }
基本上就这些。只要在可能形成闭环的地方用weak_ptr替代其中一个shared_ptr,就能有效避免循环引用带来的内存泄漏问题。关键是要理清对象间的所有权关系——拥有权用shared_ptr,观察用weak_ptr。
以上就是c++++中的std::weak_ptr怎么解决循环引用问题_c++ weak_ptr避免shared_ptr循环引用的详细内容,更多请关注其它相关文章!
# 闭环
# 浪潮营销推广活动
# 公司的网站优化方式
# 晋宁营销推广
# 在网站上怎么优化文章
# 番禺网站 优化
# 螺蛳粉营销推广预期效果
# 清远正规网站建设公司
# 弈品网站推广
# 不凡seo
# seo标题描述关键词
# 就能
# 你可以
# 回调函数
# 就会
# 流式
# 文本文件
# 多线程
# 其中一个
# 如何实现
# 回调
# red
# 作用域
# c++
# ai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
poki网页游戏推荐_poki免费游戏平台入口
CSS图片焦点样式实现教程:理解与应用tabindex属性
AO3官方可用镜像 Archive of Our Own网页版最新入口
Lar*el如何生成PDF或Excel文件_Lar*el文档导出工具与使用教程
LINUX下如何进行磁盘分区_fdisk与parted工具在LINUX中的使用对比
必由学官方网站入口 必由学学生教师共用登录通道
菜鸟取件码是什么怎么查 最全查询渠道汇总
向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程
MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复
天眼查企业查询官网入口 天眼查官方网页版查询
Go Martini框架:动态服务解码后的图片内容
不同用户不同价格! 索尼开启账户个性化定价测试
win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】
b站如何看历史记录_b站观看历史找回方法
Python大型XML文件高效流式解析教程
CSS响应式网页如何实现主次模块比例自适应_flex-grow与flex-shrink调整
C++的std::mdspan是什么_C++23中用于操作多维数组的非拥有视图
如何仅使用CSS更改登录界面背景图像图标的颜色
CSS Grid如何控制元素对齐_align-items与justify-items组合使用
微博网页版首页入口 微博电脑端官网登录链接
UC浏览器如何安装插件 UC浏览器添加扩展程序详细教程【进阶】
Go语言中对Map值调用带指针接收者方法:原理与最佳实践
地铁跑酷免费秒玩入口链接 地铁跑酷小游戏免费秒玩网站
Steam官网入口直达 Steam注册及登录步骤
小红书网页版入口链接分享 小红书官网直接进
Tabulator表格中精确实现日期时间排序的指南
AO3网页版合集入口 Archive of Our Own同人作品浏览指南
Safari浏览器输入栏卡顿如何解决 Safari搜索建议与缓存清理
Win11怎么查看显卡显存 Win11显示适配器属性及专用视频内存查询
Golang如何优雅处理error_Golang error处理最佳实践总结
Safari怎么安装扩展程序 浏览器插件安装与管理方法【详解】
拼多多购物车商品数量无法修改如何处理 拼多多购物车操作优化方法
Win11怎么开启卓越性能模式 Win11电源选项启用高性能释放硬件潜力【方法】
支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样
Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑
c++中的std::launder有什么实际用途_c++对象生命周期与指针优化
韩小圈电脑版在线入口_网页版免费登录地址
Yandex官方入口网址 Yandex俄罗斯搜索引擎最新在线地址
C++如何实现异步操作_C++11使用std::future和std::async进行异步编程
Golang如何实现Web接口签名验证_Golang Web接口签名校验开发方法
Eclipse怎么运行工程_Eclipse工程运行配置说明
学习通网页版快速入口 学习通官网网页版直接打开
PHP 枚举:根据字符串获取枚举案例的策略与实现
蛙漫2台版漫画地址 Manwa2正版网页版链接
天猫双十一预售商品怎么退款_天猫双十一预售退款操作指南
在J*aScript中复现SciPy的B样条拟合与求值:关键考量
深入理解J*aScript Promise异步执行与微任务队列
《刺客信条4:黑旗》重制版新细节曝光:无缝加载 地图更细致!
Google翻译怎么语音输入_Google翻译语音输入功能使用与设置方法
ArrayList与LinkedList操作复杂度详解:遍历与修改


2025-11-09
浏览次数:次
返回列表