全网整合营销服务商

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

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

c++怎么解决循环引用问题_c++ weak_ptr与shared_ptr配合使用【方法】

shared_ptr循环引用会导致内存泄漏,需用weak_ptr打破引用链;weak_ptr不增加引用计数,访问前须调用lock()获取临时shared_ptr,且应避免滥用以规避设计缺陷。

shared_ptr 循环引用会导致内存泄漏

当两个对象用 shared_ptr 互相持有对方时,引用计数永远无法归零,析构函数不会被调用,内存就一直卡着不释放。这不是“程序崩溃”,而是静默的资源泄露——跑得越久,占用越多。

用 weak_ptr 打破循环中的一个引用链

weak_ptr 不增加引用计数,只“观察”所指向的 shared_ptr 是否还有效。它本身不参与所有权管理,因此不会延长对象生命周期。

典型做法是:一方用 shared_ptr 持有另一方,另一方用 weak_ptr 回指——比如父类持子类的 shared_ptr,子类用 weak_ptr 指向父类。

  • 必须在访问前调用 lock() 转成临时 shared_ptr,否则可能访问已销毁对象
  • weak_ptr 不能直接解引用,也不能参与构造/赋值 shared_ptr
  • 不要长期保存 weak_ptr::lock() 返回的 shared_ptr,除非你真需要延长其生命周期

实际代码中怎么写才安全

下面是一个父子结构的最小可运行示例,展示如何避免循环引用:

#include 
#include 

struct Child;
struct Parent {
    std::shared_ptr child;
    ~Parent() { std::cout << "Parent destroyed\n"; }
};

struct Child {
    std::weak_ptr parent; // 注意:不是 shared_ptr
    ~Child() { std::cout << "Child destroyed\n"; }
};

int main() {
    auto p = std::make_shared();
    auto c = std::make_shared();
    p->child = c;
    c->parent = p; // 只是观察,不增加引用计数

    // 安全访问父对象
    if (auto locked_parent = c->parent.lock()) {
        std::cout << "Parent still alive\n";
    } else {
        std::cout << "Parent already gone\n";
    }
} // 输出:Child destroyed → Parent destroyed(顺序取决于析构时机)

weak_ptr 不是万能的,别滥用

weak_ptr 解决的是“谁该拥有谁”的设计问题,不是补丁工具。如果发现要到处加 weak_ptr,大概率是类职责或生命周期设计不合理。

常见误用包括:

  • weak_ptr 当成“可空指针”替代 shared_ptr 或裸指针——它开销更大,且每次访问都要 lock()
  • 在回调、信号槽等跨线程场景中没考虑 weak_ptr::lock() 的线程安全性(它是线程安全的,但后续使用仍需同步)
  • 忘记检查 lock() 返回是否为空,直接解引用导致未定义行为

真正关键的,是画清楚对象图、标出所有权方向,再决定哪里该用 shared_ptr、哪里该用 weak_ptr,或者干脆换用裸指针 + 明确生命周期约束。


# go  # 工具  # ai  # c++  # ios  # stream  # red  # 父类  # 子类  # 析构函数  # 循环  # 指针  # 线程  # 空指针  # 对象  # 该用  # 的是  # 是一个  # 都要  # 更大  # 它是  # 你真  # 这不是  # 越多 


相关文章: 一键网站制作软件,义乌购一件代发流程?  建站之星安装后界面空白如何解决?  深圳企业网站制作设计,在深圳如何网上全流程注册公司?  制作证书网站有哪些,全国城建培训中心证书查询官网?  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  如何在云指建站中生成FTP站点?  七夕网站制作视频,七夕大促活动怎么报名?  c++ stringstream用法详解_c++字符串与数字转换利器  再谈Python中的字符串与字符编码(推荐)  定制建站平台哪家好?企业官网搭建与快速建站方案推荐  建站主机选哪家性价比最高?  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  简历在线制作网站免费版,如何创建个人简历?  如何在腾讯云服务器快速搭建个人网站?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  视频网站制作教程,怎么样制作优酷网的小视频?  如何通过FTP服务器快速搭建网站?  实现虚拟支付需哪些建站技术支撑?  广州建站公司哪家好?十大优质服务商推荐  c# 在高并发下使用反射发射(Reflection.Emit)的性能  python的本地网站制作,如何创建本地站点?  建站主机选购指南:核心配置与性价比推荐解析  h5网站制作工具有哪些,h5页面制作工具有哪些?  C#怎么使用委托和事件 C# delegate与event编程方法  香港网站服务器数量如何影响SEO优化效果?  建站之星后台管理:高效配置与模板优化提升用户体验  建站主机选购指南:核心配置优化与品牌推荐方案  建站主机与服务器功能差异如何区分?  制作销售网站教学视频,销售网站有哪些?  网站制作说明怎么写,简述网页设计的流程并说明原因?  Java解压缩zip - 解压缩多个文件或文件夹实例  如何打造高效商业网站?建站目的决定转化率  广州美橙建站如何快速搭建多端合一网站?  中山网站推广排名,中山信息港登录入口?  建站主机无法访问?如何排查域名与服务器问题  百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?  广东专业制作网站有哪些,广东省能源集团有限公司官网?  建站OpenVZ教程与优化策略:配置指南与性能提升  建站之星如何快速生成多端适配网站?  如何在Windows 2008云服务器安全搭建网站?  常州自助建站工具推荐:低成本搭建与模板选择技巧  建站主机解析:虚拟主机配置与服务器选择指南  如何在企业微信快速生成手机电脑官网?  如何通过PHP快速构建高效问答网站功能?  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?  C#怎么创建控制台应用 C# Console App项目创建方法  如何快速搭建支持数据库操作的智能建站平台?  建站之星logo尺寸如何设置最合适?  ,柠檬视频怎样兑换vip? 

您的项目需求

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