boost库在工作(11)引用计数的智能指针weak_ptr
来源:互联网 发布:淘宝网短裤套装 编辑:程序博客网 时间:2024/06/05 15:30
由于boost库里的shared_ptr采用引用计数的技术,这个技术天生就存在一个缺陷,就是不能存在循环引用的情况,因为这个缺点,引用计数的技术一直没有用到垃圾回收的算法里。既然存在这方面的问题,作为C++强大的boost库,一定会想办法解决的。因此,就提出另外一个智能指针weak_ptr。这个智能指针只对引用的指针进行保存,但不增加引用指针的计数,因而它不对shared_ptr的指针具有拥有权,只有使用权,并且当shared_ptr的指针删除可以判断这个指针是否还有效。
我们先来看一个循环引用的例子,在这个例子里,由于循环引用导致shared_ptr的指针不会删除分配的内存,如下:
//循环引用shared_ptr,导致内存泄漏class CObjB;class CObjA{public:~CObjA(){std::cout << "~CObjA" << std::endl;}boost::shared_ptr< CObjB > m_pB;};class CObjB{public:~CObjB(){std::cout << "~CObjB" << std::endl;}boost::shared_ptr< CObjA > m_pA;};//使用weak_ptr//软件开发人员: 蔡军生 2013-02-09void TestCycle(void){//boost::shared_ptr< CObjA > pA(new CObjA);boost::shared_ptr< CObjB > pB(new CObjB);std::cout << "pA Count1:" << pA.use_count() << std::endl;std::cout << "pB Count1:" << pB.use_count() << std::endl;pA->m_pB = pB;std::cout << "pA Count2:" << pA.use_count() << std::endl;std::cout << "pB Count2:" << pB.use_count() << std::endl;pB->m_pA = pA;std::cout << "pA Count3:" << pA.use_count() << std::endl;std::cout << "pB Count3:" << pB.use_count() << std::endl;}
在上面的例子里,当函数运行完成之后,发现并没有调用析构函数,运行的结果如下:
pA Count1:1
pB Count1:1
pA Count2:1
pB Count2:2
pA Count3:2
pB Count3:2
请按任意键继续. . .
由于循环引用存在,导致引用计数不再能减到0,因此不会释放内存,导致内存泄漏出现。接着再来看一下使用weak_ptr的例子,就不会出现这种情况,如下:
//采用weak_ptr打破循环引用class CObjBW;class CObjAW{public:~CObjAW(){std::cout << "~CObjAW" << std::endl;}boost::shared_ptr< CObjBW > m_pB;};class CObjBW{public:~CObjBW(){std::cout << "~CObjBW" << std::endl;}boost::weak_ptr< CObjAW > m_pA;};void TestWeakPtr(void){//boost::shared_ptr< CObjAW > pA(new CObjAW);boost::shared_ptr< CObjBW > pB(new CObjBW);std::cout << "pA Count1:" << pA.use_count() << std::endl;std::cout << "pB Count1:" << pB.use_count() << std::endl;pA->m_pB = pB;std::cout << "pA Count2:" << pA.use_count() << std::endl;std::cout << "pB Count2:" << pB.use_count() << std::endl;pB->m_pA = pA;std::cout << "pA Count3:" << pA.use_count() << std::endl;std::cout << "pB Count3:" << pB.use_count() << std::endl;}
在这个例子里,跟前面的例子唯一的区别就是使用boost::weak_ptr,运行的结果如下:
pA Count1:1
pB Count1:1
pA Count2:1
pB Count2:2
pA Count3:2
pB Count3:2
请按任意键继续. . .
pA Count1:1
pB Count1:1
pA Count2:1
pB Count2:2
pA Count3:1
pB Count3:2
~CObjAW
~CObjBW
请按任意键继续. . .
从结果可以看到这个例子的对象会调用析构函数,因此对象也被正确地析构,表明对象的内存也回收了。
当我们发现程序有递归,或者循环引用的情况下,就需要小心智能指针shared_ptr的使用,合理地使用智能指针weak_ptr就可以避免出错。
智能指针weak_ptr还另外两个用处,当你只需要使用一下对象,但不想拥有对象生命周期,当对象删除时又得到通知。最后一个用处就是可以得到对象的指针是否有效的判断。
- boost库在工作(11)引用计数的智能指针weak_ptr
- boost库在工作(11)引用计数的智能指针weak_ptr
- boost库在工作(8)引用计数的智能指针shared_ptr之一
- boost库在工作(9)引用计数的智能指针shared_ptr之二
- boost库在工作(10)引用计数的智能指针shared_array
- boost库在工作(12)引用计数的智能指针intrusive_ptr
- boost库在工作(8)引用计数的智能指针shared_ptr之一
- boost库在工作(9)引用计数的智能指针shared_ptr之二
- boost库在工作(10)引用计数的智能指针shared_array
- boost库在工作(12)引用计数的智能指针intrusive_ptr
- 智能指针boost::weak_ptr
- 详解Boost库智能指针(shared_ptr && scoped_ptr && weak_ptr )
- (推荐)智能指针boost::weak_ptr 详解
- (推荐)智能指针boost::weak_ptr 详解
- 引用计数智能指针std::tr1::shared_ptr与weak_ptr
- 建议慎用boost::weak_ptr来避免智能指针循环引用
- 几种智能指针的比较(std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::weak_ptr)
- Boost智能指针—weak_ptr
- PreviewHandler用法(一)
- 苹果iphone4s英文系统怎么显示中文联系人?
- Java虚拟机之线程同步
- 李开复关于时间管理的回答
- Flex 问题_关于unable to open
- boost库在工作(11)引用计数的智能指针weak_ptr
- ENDNOTE使用方法
- 编写内核模块遍历进程的PID
- PreviewHandler用法(二)
- 鸟菜呀鸟菜,入门级ajax调用
- 当你输入一个网址的时候,实际会发生什么?
- 深入理解Oracle索引(7):用实验数据观察从B-tree索引→复合索引→Bitmap索引所消费的CPU和I/O
- 好奇号登陆火星
- Windows同步对象Event和Linux的条件变量