文档章节

智能指针std::weak_ptr

o
 osc_y8yehimr
发布于 2019/03/20 19:30
字数 905
阅读 3
收藏 0

钉钉、微博极速扩容黑科技,点击观看阿里云弹性计算年度发布会!>>>

std::weak_ptr

避免shared_ptr内存泄漏的利器。👈


smart pointer 三兄弟性格各异。unque_ptr是独来独往,shared_ptr是左拥右抱,而weak_ptr生来就不是为了单打独斗,了解之后你会发现他总是和shared_ptr出双入对。

既然shared_ptr是智能指针,那理所应当不会发生内存泄漏,那么为什么👆还会说“避免shared_ptr内存泄漏”呢?我们不禁疑惑👇

shared_ptr怎么导致的内存泄漏?

我们知道shared_ptr的特性是:内含一个计数器(可能是计数器,也可能其他数据结构),掌握着share某对象的指针的数量(shared_ptr.use_count()可知),当计数器值为0时,它寿终正寝连带它的对象也一起陪葬(被它的析构函数销毁),好不霸道。但就是这么强势的它,也有翻船(发生内存泄漏)的时候---循环引用

看👇的例子

 1 #include <iostream>
 2 #include <memory>
 3 using namespace std;
 4 
 5 class B;
 6 class A
 7 {
 8 public:
 9     A() { cout << "A's constructor ..." << endl; }
10     ~A() { cout << "A's destructor ..." << endl; }
11     
12     std::shared_ptr<B> b;//class A中含有指向class B的shared指针
13 };
14 
15 class B
16 {
17 public:
18     B() { cout << "B's constructor ..." << endl; }
19     ~B() { cout << "B's destructor ..." << endl; }
20 
21     std::shared_ptr<A> a; //class B 中含有指向class A的shared指针
22 };
23 
25 int main() 
26 {
27     std::shared_ptr<A> aa = make_shared<A>(); //aa->object A  aa计数器 1
28     std::shared_ptr<B> bb = make_shared<B>(); //bb->object B  bb计数器 1
29 
30     aa->b = bb;// aa 计数器来到了 2
31     bb->a = aa;// bb 计数器来到了 2
32 
33     return 0;
34 }

class A中含有指向class B的shared指针, class B 中含有指向class A的shared指针,这样形成了循环引用。
我们来看输出结果👇

可以看到,两个类对象都进行了构造,却没有析构销毁掉,发生了内存泄漏⚡⚡

为什么呢?其实,在执行完一下语句后,shared_ptr计数器就加到了2,而出了main函数作用域,其计数会-1,成为 1,不为0,所以该对象未被析构(销毁)。

aa->b = bb;// aa 计数器来到了 2
bb->a = aa;// bb 计数器来到了 2

这可如何是好,连智能指针都出现内存泄露了,我还是回去用我的一般指针?当然不是!

❇❇weak_ptr闪亮登场❇❇

weak_ptr为什么存在?

特性:

不可使用* 和 ->访问对象

被赋值,不会引起shared_ptr内部计数器值变化(我猜是它严格上来说不具备指针的能力---访问对象)

 所以,我们就可以用weak_ptr替代shared_ptr, 看👇例子。

 1 #include <iostream>
 2 #include <memory>
 3 using namespace std;
 4 
 5 class B;
 6 class A
 7 {
 8 public:
 9     A() { cout << "A's constructor ..." << endl; }
10     ~A() { cout << "A's destructor ..." << endl; }
11     
12     std::weak_ptr<B> weak_b;
13 };
14 
15 class B
16 {
17 public:
18     B() { cout << "B's constructor ..." << endl; }
19     ~B() { cout << "B's destructor ..." << endl; }
20 
21     std::weak_ptr<A> weak_a;
22 };
23 
25 int main() 
26 {
27     std::shared_ptr<A> aa = make_shared<A>(); //aa->object A aa计数器 1
28     std::shared_ptr<B> bb = make_shared<B>(); //bb->object B bb计数器 1
29 
30     aa->weak_b = bb; //计数器还是1哦
31     bb->weak_a = aa; //计数器还是1哦
32 
33     return 0;
34 }

再来看下结果👇

object A & B都被成功析构(销毁)了。那么循环引用导致shared_ptr发生内存泄漏的问题迎刃而解!

原因是:weak_ptr不会增加shared_ptr的计数器,从而离开mian函数作用域时,shared_ptr aa & bb 计数器都 -1 ,成为0, 具备销毁条件,调用析构函数销毁自己和所指对象

至此,我们终于可以说weak_ptr具备避免内存泄漏的功能了!!!


 

 参考:https://www.cnblogs.com/DswCnblog/p/5628314.html

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)

几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智能指针 4. weakedptr: 到 std::shared_...

osc_byhxg8pe
2019/05/02
13
0
C++11智能指针

  为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer)。   智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,C++中有一个重要原则,在函...

osc_wqha5akl
2018/06/15
1
0
C++11智能指针

前言 最近一段时间看代码,里面用到了C++的智能指针,发现自己竟然看不懂代码在表达什么意思,所以专门抽个时间恶补一下自己这方面欠缺的知识。 参考书籍《深入应用C++11:代码优化与工程级应...

osc_9sy7s563
2018/06/05
2
0
智能指针shared_ptr新特性shared_from_this及weak_ptr

enablesharedfrom_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enablesharedfromthis; std::enablesharedfromthis 能让一个对象(假设其名为 t ,且已被......

osc_962c7vo6
2019/04/08
8
0
C++智能指针解决内存泄漏问题

在C++开发中,好多程序员经常会被内存泄漏问题困扰,使用智能指针就可以减少内存泄漏。智能指针可以自动删除分配的内存。智能指针和普通指针类似,只是不需要手动释放指针,而是通过智能指针...

AllenOR灵感
2018/01/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java架构师成长路线-高并发网络编程的分类

鲁班学院java架构师成长路线 随着互联网时代的到来,高并发网络编程这一新鲜名词早已跃然于纸上,为了满足大众眼光的需求,我为大家找了些关于高并发网络编程方面的资料,本文便来介绍高并发...

osc_o494ayqf
5分钟前
0
0
python dict乱码如何解决

定义字典并直接输出,结果输出结果中文是乱码展示 d={'name':'lily','age':18,'sex':'女','no':1121}print d 输出结果: {'age': 18, 'no': 1121, 'name': 'lily', 'sex': '\xe5\xa5\xb3'}...

osc_9mjo6c4e
6分钟前
0
0
硬肝50天,18w字的实战编程资料《重学Java设计模式》终于 出炉了

沉淀、分享、成长,让自己和他人都能有所收获! 一、前言 作者从5月20日那天投身实战型设计模式打磨,通过模拟互联网业务开发实际需求作为学习场景,讲解设计模式。 全书共计22个真实业务场景...

osc_zls6dx9i
8分钟前
9
0
怎么才能让Spring AOP有最大的作用--乐字节java

Spring AOP 日志处理带来的问题 我们有一个Pay(接口) 然后两个实现类DollarPay和RmbPay,都需要重写pay()方法, 这时我们需要对pay方法进行性能监控,日志的添加等等怎么做? 最容易想到的方法...

osc_sb30h1xb
9分钟前
0
0
Python 实现将numpy中的nan和inf,nan替换成对应的均值

nan:not a number inf:infinity;正无穷 numpy中的nan和inf都是float类型 t!=t 返回bool类型的数组(矩阵) np.count_nonzero() 返回的是数组中的非0元素个数;true的个数。 np.isnan() 返回b...

osc_sfl7wfr9
11分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部