【C++编程】weak_ptr
正文
weak_ptr 详解
#include <iostream>
#include <memory>
class CB;
class CA
{
public:
CA() { std::cout << "CA()" << std::endl; }
~CA() { std::cout << "~CA()" << std::endl; }
void set_ptr(std::shared_ptr<CB> &ptr) { m_ptr_b = ptr; }
private:
std::shared_ptr<CB> m_ptr_b;
};
class CB
{
public:
CB() { std::cout << "CB()" << std::endl; }
~CB() { std::cout << "~CB()" << std::endl; }
void set_ptr(std::shared_ptr<CA> &ptr) { m_ptr_a = ptr; }
private:
std::shared_ptr<CA> m_ptr_a;
};
int main()
{
std::shared_ptr<CA> ptr_a(new CA());
std::shared_ptr<CB> ptr_b(new CB());
ptr_a->set_ptr(ptr_b);
ptr_b->set_ptr(ptr_a);
std::cout << ptr_a.use_count() << " " << ptr_b.use_count() << std::endl;
return 0;
}
既然析构函数没有调用,就说明ptr_a
和ptr_b
两个变量的引用计数都不是0。
分析一下引用情况
#include <iostream>
#include <memory>
class CB;
class CA
{
public:
CA() { std::cout << "CA()" << std::endl; }
~CA() { std::cout << "~CA()" << std::endl; }
void set_ptr(std::shared_ptr<CB>& ptr) { m_ptr_b = ptr; }
private:
std::shared_ptr<CB> m_ptr_b;
};
class CB
{
public:
CB() { std::cout << "CB()" << std::endl; }
~CB() { std::cout << "~CB()" << std::endl; }
void set_ptr(std::shared_ptr<CA>& ptr) { m_ptr_a = ptr; }
private:
std::weak_ptr<CA> m_ptr_a;
};
int main()
{
std::shared_ptr<CA> ptr_a(new CA());
std::shared_ptr<CB> ptr_b(new CB());
ptr_a->set_ptr(ptr_b);
ptr_b->set_ptr(ptr_a);
std::cout << ptr_a.use_count() << " " << ptr_b.use_count() << std::endl;
return 0;
}
流程与上一例子大体相似,但是不同的是4这条引用是通过weak_ptr
建立的,并不会增加引用计数。也就是说,CA的对象只有一个引用计数,而CB的对象只有两个引用计数,当main函数返回时,对象ptr_a
和ptr_b
被销毁,也就是1,3两条引用会被断开,此时CA对象的引用计数会减为0,对象被销毁,进而解决了引用成环的问题。
参考资料
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
2018-06-03 【学习工具】vmware克隆独立虚拟机及初始配置
2018-06-03 【C++ 继承】重载、重写、隐藏的区别
2018-06-03 【rpm】创建子包