【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配合使用,不能单独使用.
转载于:https://www.cnblogs.com/qq329914874/p/6661578.html
【C++】智能指针简述(五):解决循环引用的weak_ptr相关推荐
- 解决循环引用--弱引用weak_ptr
循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象.一个简单的例子如下: class parent; class children;typedef sh ...
- weak_ptr 的几个应用场景 —— 观察者、解决循环引用、弱回调
weak_ptr 弱智能指针 Effecvive Modern C++ 使用std::weak_ptr 来代替可能空悬的 std:: shared_ptr . std::weak_ptr 可能的用武之 ...
- python垃圾回收机制为什么标记能解决循环引用问题_Python 垃圾回收机制和如何解决循环引用...
引用计数:是一种垃圾收集机制,而且也是一种最直观,最简单的垃圾收集技术, 当一个对象的引用被创建或者复制时,对象的引用计数加 1:当一个对象的引用被销毁时,对象的引用计数减 1:当对象的引用计数减少为 ...
- NSTimer解决循环引用常见方法
1. NSTimer的使用 常见使用场景如下: - (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColo ...
- js深拷贝,解决循环引用
概念 前提为拷贝类型为引用类型的情况下: 浅拷贝是拷贝一层,属性为对象时,浅拷贝是复制,两个对象指向同一个地址 深拷贝是递归拷贝深层次,属性为对象时,深拷贝是新开栈,两个对象指向不同的地址 浅拷贝的方 ...
- php 解决循环引用,excel循环引用如何解决
excel循环引用如何解决? 方法一 需要找到"excel选项",这个地方在Office 2003版本里的"工具"选项里,而在Office 2007版本里不好找 ...
- java中出现循环问题如何解决_java如何解决循环引用
Excel 循环引用产生的原因及解决方法 来源:excel 格子社区 我们打开 ... (Garbage Collection Thread) , 来跟踪每一块分配出去的内存空间, Java 虚拟机 ...
- block为什么用copy以及如何解决循环引用
在完成项目期间,不可避免的会使用到block,因为block有着比delegate和notification可读性更高,而且看起来代码也会很简洁.于是在目前的项目中大量的使用block. 之前给大家介 ...
- Flask-分开Models解决循环引用
在之前我们测试中,所有语句都在同一个文件中,但随着项目越来越大,管理起来有所不便,所以将Models分离. 基本的文件结构如下 \-–app.py \-–models.py from flask im ...
最新文章
- 从前端程序员的视角看小程序的稳定性保障
- 梯度下降法与牛顿法的比较
- c语言字符串去重简单,C语言实现简单飞机大战
- 宜昌远安谋定功能性-农业大健康·万祥军:绿色和谐新路
- php获取随机图片,PHP 随机显示某张图片
- EFCore之增删改查
- mysql connector c编程_MySQL数据库之MySQL Connector 编程
- java多线程 run start_java多线程中run和start区别
- MySQL字符串拼接函数使用
- Cisco 模拟器rstp生成树
- 微信朋友圈装x代码_微信朋友圈写入代码 微信朋友圈代码大全
- 码code | 拒绝996,不用服务器也能高效开发小游戏
- oracle10g dblink优化,dblink如果很慢可以用这种方式优化
- 原生Winows7系统添加USB3.0的驱动
- 菜孔孔学python--集合
- Python Tensorflow + CNN + Opencv 英雄联盟小地图识别,LOL Minimap Scanner
- C语言中sort函数的用处
- 自动化测试C语言程序,初级自动化测试笔试题
- PL/SQL中的dual表含义和用法
- Pytorch squeeze()的简单用法