【C++】智能指针简述(五):解决循环引用的weak_ptr
总结一下前文内容:
1.智能指针通过RAII方法来管理指针:构造对象时,完成资源初始化;析构对象时,对资源进行清理及汕尾.
2.auto_ptr,通过“转移所有权”来防止析构一块内存多次.(如何转移?详情看第二篇文章)
3.scoped_ptr,不“转移所有权”而是禁止拷贝/赋值对象.(C++如何禁止拷贝对象?详情看第三篇文章)
4.shared_ptr,通过"引用计数"的方法,来完成对象的拷贝/赋值.(引用计数怎么实现?详情看上篇文章)
大致总结了一下前文后,我们开始讨论今天的内容:解决智能指针的循环引用问题!
我们先来看一下这样的场景:
template<typename T>
struct ListNode{
T _value;
std::shared_ptr<ListNode> _prev;
std::shared_ptr<ListNode> _next; ListNode(const T & value)
:_value(value)
,_prev(NULL)
,_next(NULL){} ~ListNode(){
std::cout<<"~ListNode()"<<std::endl;
}
}; void TestWeekPtr(){
std::shared_ptr<ListNode<int>> sp1(new ListNode<int>(10));
std::shared_ptr<ListNode<int>> sp2(new ListNode<int>(20));
sp1->_next = sp2;
sp2->_prev = sp1;
//构成死锁,出了函数作用域,也没有调用析构函数
std::cout<<sp1.use_count()<<std::endl; //sp1的引用计数
std::cout<<sp2.use_count()<<std::endl; //sp2的引用计数
}
sp1指向sp2、sp2又指向sp1,这种情况,就好像两个人打架:互相抓住对方耳朵,A说你先松手,你不松我就不松;B说你先松,你不松我也不松.就这样一直僵持着.....
那么,我们如何解决这样的问题呢?
用weak_ptr!!!
template<typename T>
struct ListNode{
T _value;
weak_ptr<ListNode> _prev;
weak_ptr<ListNode> _next; ListNode(const T & value)
:_value(value)
,_prev(NULL)
,_next(NULL){} ~ListNode(){
std::cout<<"~ListNode()"<<std::endl;
}
};
void TestWeekPtr(){
std::shared_ptr<ListNode<int>> sp1(new ListNode<int>(10));
std::shared_ptr<ListNode<int>> sp2(new ListNode<int>(20));
sp1->_next = sp2;
sp2->_prev = sp1; std::cout<<sp1.use_count()<<std::endl;
std::cout<<sp2.use_count()<<std::endl;
}
那么为什么用weak_ptr就可以解决循环引用的问题,简单点的来说:weak_ptr的构造和析构不会引起引用计数的增加或减少.
最后,作为补充:weak_ptr必须与shared_ptr配合使用,不能单独使用.
【C++】智能指针简述(五):解决循环引用的weak_ptr的更多相关文章
- 智能指针 auto_ptr、scoped_ptr、shared_ptr、weak_ptr
什么是RAII? RAII是Resource Acquisition Is Initialization的简称,是C++语言的一种管理资源.避免泄漏的惯用法. RAII又叫做资源分配即初始化,即:定义 ...
- 深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用(上)
深入研究Block捕获外部变量和__block实现原理 前言 在上篇中,仔细分析了一下Block的实现原理以及__block捕获外部变量的原理.然而实际使用Block过程中,还是会遇到一些问题,比如R ...
- swift闭包中解决循环引用的问题
swift中可以通过三种方法解决循环引用的问题 利用类似oc方法解决循环引用weak var weakSelf = self weak var weakSelf = self loadData = { ...
- Flask-分开Models解决循环引用
Flask-分开Models解决循环引用 在之前我们测试中,所有语句都在同一个文件中,但随着项目越来越大,管理起来有所不便,所以将Models分离.基本的文件结构如下 \—–app.py\—–mode ...
- 【C++】智能指针简述(六):智能指针总结及补充
本文我们主要来总结一下前文介绍过的智能指针相关原理及实现,顺便补充一下前文未提到的shared_ptr删除器部分的内容. 总结: 1.智能指针,通过RAII机制,构造对象时完成资源的初始化,析构对象时 ...
- block为什么用copy以及如何解决循环引用
在完成项目期间,不可避免的会使用到block,因为block有着比delegate和notification可读性更高,而且看起来代码也会很简洁.于是在目前的项目中大量的使用block. 之前给大家介 ...
- 如何在 iOS 中解决循环引用的问题
稍有常识的人都知道在 iOS 开发时,我们经常会遇到循环引用的问题,比如两个强指针相互引用,但是这种简单的情况作为稍有经验的开发者都会轻松地查找出来. 但是遇到下面这样的情况,如果只看其实现代码,也很 ...
- Swift-闭包使用及解决循环引用问题
Swift中闭包使用参考OC中block使用,基本一致 // 闭包类型 首先写(参数列表)->(返回值类型) func loadData(callBack : (jsonData:String) ...
- 第八章 springboot + mybatis + 多数据源2(解决循环引用)
解决了循环引用 1.application.properties #the first datasource jdbc.names:1,2 jdbc1.driverClassName = com.my ...
随机推荐
- mybatis中批量插入数据
<insert id="insertIntoDevAct" parameterType="java.util.List"><foreach c ...
- linux设备驱动归纳总结(八):2.match.probe.remove
linux设备驱动归纳总结(八):2.总线.设备和驱动的关系 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- Lint工具去除Android工程里不再需要的资源
摘要: 在项目开发过程中常常会不断改UI设计,于是在定稿要发布的前夕,发现有好多不再需要的资源文件存在,发布的包会把这些无用的资源都包含在里面,造成APK的下载包过大.可以通过Android SDK自 ...
- Android学习笔记-保存数据的实现方法1
Android开发中,有时候我们需要对信息进行保存,那么今天就来介绍一下,保存文件到内存,以及SD卡的一些操作,及方法,供参考. 第一种,保存数据到内存中: //java开发中的保存数据的方式 pub ...
- [软件分享]aboboo英语复读机 使用心得
软件名称:aboboo www.aboboo.com 作用:英语复读,社区互动,丰富的材料,可以全方位锻炼听说能力. 技巧1:如何锻炼口语? 注册一个帐号,登陆后下载使用社区自带的课件,然后使用“随意 ...
- Codeforces Round #324 (Div. 2)D. Dima and Lisa 数学(素数)
D. Dima and Lisa Dima loves representing an odd num ...
- UIColor与十六进制字符串互转
UIColor转十六进制字符串 方法一:经过测试发现部分颜色会转化为#fffff(五个f),转化残缺导致最后颜色无法还原,不推荐使用. // UIColor转#ffffff格式的字符串 + (NSSt ...
- 7-81 js课程小结
7-81 js课程小结 学习要点 理解全局对象 变量的作用范围 理解全局对象Global 全局属性和函数可用于所有内建的 JavaScript 对象.全局对象是所有全局方法的拥有者,用来统一管理全局方 ...
- android.content.ReceiverCallNotAllowedException: 解决方法
一. android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to reg ...
- luogu3941入阵曲
https://www.zybuluo.com/ysner/note/1301562 题面 统计在给出的\(n*m\)矩阵中,有多少个不同的子矩形中的数字之和是\(k\)的倍数? 解析 切不掉这道题是 ...