weak_ptr打破环状引用
来源:互联网 发布:手机剪辑视频软件 编辑:程序博客网 时间:2024/04/28 00:54
weak_ptr是一种不控制对象生存周期的智能指针,它指向一个shared_ptr管理的对象...它不会改变shared_ptr的引用计数——《C++ Primer .5th》。很明显,weak_ptr的特点是“弱引用”。有什么用?应用场景是什么地方?
考虑它的胞兄shared_ptr,每次复制之后引用计数加一,不再指向对象(自身销毁或指向其他对象)时时引用计数减一,减至零值调用所管理资源对象的析构函数。考虑这样一个情况,两个对象各自包含指向彼此的shared_ptr成员,形成环状引用,引用计数永远为1,不能销毁,造成内存泄漏。
//x86_64 win7_64 vs2013 ultimate #include <iostream> #include <string> #include <memory> using namespace std; class A; class B; class A{ public: ~A(){ cout << "destroying A\n" ; } shared_ptr<B> pb; }; class B{ public: ~B(){ cout << "destroying B\n" ; } shared_ptr<A> pa; }; void test(){ shared_ptr<A> a(new A()); shared_ptr<B> b(new B()); a->pb = b; b->pa = a; } int main(){ cout << "begin test...\n"; test(); cout << "end test\n"; } output: begin test... end test 请按任意键继续. . .
在函数test()中便是刚才提到的情形,A、B的对象分别被彼此的shared_ptr所引用,离开test()作用域后,A、B对象再也不能被用户访问,因为智能指针a、b被销毁了,但是各自引用计数为1,两个对象的内存再也不会被释放,可怕的内存泄漏就此产生。
那么weak_ptr对此又有帮助呢?考虑如果将B中的智能指针换成weak_ptr<A>,回过头看test()里发生了什么?首先shared_ptr版本的a、b初始化,引用计数各自为1,然后将b赋值给A中的shared_ptr,B对象引用计数变为2,将a赋值给B中的weak_ptr,此操作不改变shared_ptr<A>的引用计数,依旧为1。退出test作用域,a、b析构,B引用计数变为1,A的引用计数为0。A的析构函数被调用,A中的shared_ptr<B>也被销毁,即B的引用计数再次减1变为0,调用B的析构函数。此时,内存已经被全部回收。
1 class B{ 2 public: 3 ~B(){ cout << "destroying B\n" << endl; } 4 weak_ptr<A> pa; 5 }; 6 output: 7 begin test... 8 destroying A 9 10 destroying B 11 12 end test 13 请按任意键继续.
实际用用的例子,想象在一个tree结构中,父节点通过一个共享所有权的引用(chared_ptr)引用子节点,同时子节点又必须持有父节点的引用。如果这第二个引用也共享所有权,就会导致一个循环,最终两个节点内存都无法释放。
- weak_ptr打破环状引用
- weak_ptr打破环状引用
- 使用weak_ptr打破shared_ptr循环引用
- weak_ptr解决shared_ptr环状引用所引起的内存泄漏
- weak_ptr解决shared_ptr环状引用所引起的内存泄漏
- weak_ptr解决shared_ptr环状引用所引起的内存泄漏
- weak_ptr解决shared_ptr环状引用所引起的内存泄漏
- weak_ptr 弱引用打破智能指针中循环引用造成的内存泄露
- weak_ptr解除循环引用
- shared_ptr 之循环引用 weak_ptr
- weak_ptr解决循环引用问题demo
- weak_ptr
- weak_ptr
- weak_ptr
- weak_ptr
- weak_ptr
- weak_ptr
- 弱引用weak_ptr 解决shared_ptr的循环引用
- 3562: [SHOI2014]神奇化合物
- STL-迭代器与traits技法
- Android自定义控件_基础(五)
- NAT技术与代理服务器
- jzoj3452 【NOIP2013中秋节模拟】长方形(rectangle)
- weak_ptr打破环状引用
- Android开发之 popupwindow
- 5-1 字符串的冒泡排序 (20分)
- PHP基础及ThinkPHP
- 快速复制大文件、多个文件
- 多选框select美化chosen.js的使用
- TCP协议字段中的URG和PSH
- jzoj3453【NOIP2013中秋节模拟】连通块(connect,并查集,二维)
- java 对象集合去重记录