码迷,mamicode.com
首页 > 其他好文 > 详细

智能指针std::weak_ptr

时间:2021-01-20 11:45:59      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:object   share   它的   main   出现   智能指针   cout   str   info   

 

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 }
View Code
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 }
View Code

再来看下结果??

技术图片

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

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

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

 参考https://www.cnblogs.com/yocichen/p/10563124.html

智能指针std::weak_ptr

标签:object   share   它的   main   出现   智能指针   cout   str   info   

原文地址:https://www.cnblogs.com/gary-guo/p/14297859.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!