首页 > 后端开发 > C++ > 正文

c++中如何使用weak_ptr解决循环引用_c++ weak_ptr解决循环依赖方法

穿越時空
发布: 2025-09-30 14:07:02
原创
450人浏览过
循环引用指两个对象的shared_ptr相互持有,导致引用计数无法归零而内存泄漏;解决方法是将其中一个改为weak_ptr,如B类中用std::weak_ptr代替shared_ptr,打破循环,使对象能正常析构。

c++中如何使用weak_ptr解决循环引用_c++ weak_ptr解决循环依赖方法

在C++中,shared_ptr 能自动管理对象生命周期,但当两个对象互相持有对方的 shared_ptr 时,就会产生循环引用,导致内存无法释放。这时就需要用 weak_ptr 来打破循环。

什么是循环引用?

考虑两个类 A 和 B,A 持有指向 B 的 shared_ptr,B 也持有指向 A 的 shared_ptr:

struct B;

struct A {
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A destroyed\n"; }
};

struct B {
    std::shared_ptr<A> a_ptr;
    ~B() { std::cout << "B destroyed\n"; }
};
登录后复制

如果这样创建对象:

auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->b_ptr = b;
b->a_ptr = a;
登录后复制

此时 a 和 b 的引用计数都为2。离开作用域后,a 和 b 的 shared_ptr 被销毁,引用计数减为1,但不会归零,析构函数不被调用,造成内存泄漏。

立即学习C++免费学习笔记(深入)”;

用 weak_ptr 打破循环

解决方法是:将其中一个引用改为 weak_ptr,它不增加引用计数,只观察对象是否存在。

AppMall应用商店
AppMall应用商店

AI应用商店,提供即时交付、按需付费的人工智能应用服务

AppMall应用商店 56
查看详情 AppMall应用商店

修改上面的代码:

struct B;

struct A {
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A destroyed\n"; }
};

struct B {
    std::weak_ptr<A> a_ptr;  // 改为 weak_ptr
    ~B() { std::cout << "B destroyed\n"; }
};
登录后复制

现在 B 持有的是指向 A 的 weak_ptr,不会增加 A 的引用计数。当外部 shared_ptr 离开作用域,A 的引用计数变为0,A 被销毁;接着 B 的 b_ptr 失效,B 的引用计数也归零,B 被销毁。

如何安全使用 weak_ptr

由于 weak_ptr 不保证所指对象一定存在,访问前必须检查:

  • 使用 lock() 获取 shared_ptr:如果对象还活着,返回有效的 shared_ptr;否则返回 nullptr
  • 使用 expired() 判断对象是否已销毁(不推荐,有竞态风险)

示例:

std::shared_ptr<A> get_a(std::weak_ptr<A>& a_weak) {
    if (auto a = a_weak.lock()) {
        return a;
    } else {
        std::cout << "A 已被销毁\n";
        return nullptr;
    }
}
登录后复制

基本上就这些。只要在可能形成闭环的地方把非拥有性引用换成 weak_ptr,就能有效防止循环引用问题。关键是分清谁真正拥有对象,谁只是临时观察。拥有关系用 shared_ptr,观察用 weak_ptr。不复杂但容易忽略。

以上就是c++++中如何使用weak_ptr解决循环引用_c++ weak_ptr解决循环依赖方法的详细内容,更多请关注php中文网其它相关文章!

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号