全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

c++中如何使用weak_ptr_c++弱引用智能指针解决循环引用

weak_ptr是不增加引用计数的智能指针,用于打破shared_ptr循环引用;它仅观察对象,需通过lock()获取临时shared_ptr来安全访问资源。

weak_ptr 是什么,为什么能破循环引用

在 C++ 中,shared_ptr 通过引用计数管理资源生命周期,但两个 shared_ptr 相互持有(比如 A 持有 B 的 shared_ptr,B 也持有 A 的 shared_ptr),会导致引用计数永远不为 0,资源无法释放——这就是循环引用。weak_ptr 不增加引用计数,只“观察”一个由 shared_ptr 管理的对象,因此可用来打破这种僵局。

典型场景:父子类双向关联时怎么用 weak_ptr

常见于树节点、观察者模式、容器与元素互相持有等结构。关键原则是:**一方用 shared_ptr 拥有对方,另一方用 weak_ptr 观察对方**,避免双向强引用。

  • 父节点通常“拥有”子节点 → 子节点用 shared_ptr 存在父节点的 vector>
  • 子节点需要访问父节点但不该延长其生命周期 → 子节点中存 weak_ptr 而非 shared_ptr
  • 使用前必须调用 lock() 获取临时 shared_ptr,检查是否仍有效
struct Node {
    std::shared_ptr parent;
    std::vector> children;
    // ✅ 正确:用 weak_ptr 避免反向强引用
    std::weak_ptr back_to_parent;
void set_parent(std::shared_ptrzuojiankuohaophpcnNodeyoujiankuohaophpcn p) {
    parent = p;
    // ✅ 安全赋值:weak_ptr 不影响引用计数
    back_to_parent = p;
}

void use_parent() {
    // ✅ 必须 lock() 并检查,防止访问已销毁对象
    if (auto p = back_to_parent.lock()) {
        std::cout zuojiankuohaophpcnzuojiankuohaophpcn "Parent still alive\n";
    } else {
        std::cout zuojiankuohaophpcnzuojiankuohaophpcn "Parent gone\n";
    }
}

};

weak_ptr.lock() 和 expired() 的区别与误用风险

lock() 返回 shared_ptr,内部做原子检查+增计数;expired() 只检查引用计数是否为 0,不加锁也不增计数。二者不是等价的判断方式。

  • ❌ 错误写法:if (!ptr.expired()) { auto s = ptr.lock(); /* 使用 s */ } —— 中间可能发生析构,lock() 返回空
  • ✅ 正确写法:直接 if (auto s = ptr.lock()) { /* 使用 s */ },一次原子操作完成检查和获取
  • expired() 适合仅需“快照式”判断(如日志、调试),不用于后续访问资源的分支逻辑

注意:weak_ptr 不能直接构造,也不能指向裸指针

weak_ptr 只能从 shared_ptr 构造(拷贝或赋值),且必须与该 shared_ptr 共享同一控制块。试图用裸指针或 unique_ptr 初始化会编译失败。

  • std::weak_ptr wp(new int(42)); —— 编译错误
  • std::weak_ptr wp(std::move(up));(up 是 unique_ptr)—— 无对应构造函数
  • std::shared_ptr sp = std::make_shared(42); std::weak_ptr wp = sp;
  • ⚠️ 即使 sp 被 move 走,只要还有其他 shared_ptr 存活,wp.lock() 仍可能成功

真正容易被忽略的是:weak_ptr 的存在本身不阻止对象销毁,但它依赖的控制块(control block)会在最后一个 shared_ptr 和最后一个 weak_ptr 都析构后才释放。如果大量长期存在的 weak_ptr 不清理,会拖慢控制块回收——尤其在高频创建/销毁对象的场景中,得留意 weak_ptr 的生命周期管理。


# node  # go  # c++  # 区别  # 编译错误  # 为什么  # red  # if  # 子类  # 构造函数  # auto  # int  # 循环  # 指针  # 对象  # 的是  # 也不  # 这就是  # 则是  # 会在  # 不为  # 而非  # 但它  # 后才  # 仅需 


相关文章: 胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  网站制作网站,深圳做网站哪家比较好?  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  定制建站模板如何实现SEO优化与智能系统配置?18字教程  深圳网站制作案例,网页的相关名词有哪些?  如何在阿里云购买域名并搭建网站?  如何通过西部数码建站助手快速创建专业网站?  建站之星在线版空间:自助建站+智能模板一键生成方案  ,在苏州找工作,上哪个网站比较好?  ,网页ppt怎么弄成自己的ppt?  linux top下的 minerd 木马清除方法  建站中国官网:模板定制+SEO优化+建站流程一站式指南  如何通过可视化优化提升建站效果?  专业网站建设制作报价,网页设计制作要考什么证?  网站制作难吗安全吗,做一个网站需要多久时间?  如何在建站宝盒中设置产品搜索功能?  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  如何在云主机上快速搭建网站?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  如何快速搭建高效简练网站?  如何快速生成高效建站系统源代码?  c# 在高并发场景下,委托和接口调用的性能对比  如何选择域名并搭建高效网站?  定制建站方案优化指南:企业官网开发与建站费用解析  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  西安专业网站制作公司有哪些,陕西省建行官方网站?  平台云上自主建站:模板化设计与智能工具打造高效网站  建站之星安装需要哪些步骤及注意事项?  如何零基础在云服务器搭建WordPress站点?  南平网站制作公司,2025年南平市事业单位报名时间?  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  建站之星安装后如何配置SEO及设计样式?  建站之星如何防范黑客攻击与数据泄露?  制作网页的网站有哪些,电脑上怎么做网页?  临沂网站制作企业,临沂第三中学官方网站?  免费公司网站制作软件,如何申请免费主页空间做自己的网站?  建站OpenVZ教程与优化策略:配置指南与性能提升  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?  如何选择适合PHP云建站的开源框架?  ,sp开头的版面叫什么?  ,柠檬视频怎样兑换vip?  浅谈Javascript中的Label语句  云南网站制作公司有哪些,云南最好的招聘网站是哪个?  为什么Go需要go mod文件_Go go mod文件作用说明  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  如何用好域名打造高点击率的自主建站?  整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。