传说中的神器: shared_ptr/weak_ptr/scoped_ptr
《Linux多线程服务端编程》称 shared_ptr/weak_ptr 之为神器。
in multi-threading programming, we sometime get core dump when delete som obj ,even if we has do the check:
if(obj) delete obj;
However, core dump some out sometimes not always. My preview article has said something about this. And I avoid the problem by NOT delete them , using singleton pattern or ajust my logic.
Yet, this artile is the right solution for multi-threading programming.
#include <string.h> #include <iostream> #include <boost/shared_ptr.hpp> class implementation { public: ~implementation(){std::cout<<"destroying implementation\n";} void do_something(){std::cout<<"did something\n";} }; void test() { boost::shared_ptr<implementation> sp1(new implementation); std::cout<< "The Sample now has "<< sp1.use_count()<< " reference(sp1)\n"; //boost::shared_ptr<implementation> sp2(new implementation); boost::shared_ptr<implementation> sp2 = sp1; std::cout<< "The Sample now has "<< sp1.use_count()<< " reference(sp1)\n"; std::cout<< "The Sample now has "<< sp2.use_count()<< " reference(sp2)\n"; sp1.reset(); std::cout<<"After Reset sp1. The Sample now has "<<sp1.use_count()<< " reference\n"; std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<< " reference(sp2)\n"; sp2.reset();//will call for ~implementation std::cout<<"After Reset sp2. The Sample now has "<<sp2.use_count()<< " reference\n"; } int main(void) { test(); return 0; }
=========================================================
For loop reference case , use weak_ptr
#include <string.h> #include <iostream> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> class parent; class children; typedef boost::shared_ptr<parent> parent_ptr; typedef boost::shared_ptr<children> children_ptr; class parent { public: ~parent(){std::cout<<"destroying parent\n";} public: boost::weak_ptr<children> child; //changed from ori blog -- cause there was a complie error if use boost::weak_ptr<children> children // children_ptr children; }; class children { public: ~children(){std::cout<<"destroying children\n";} public: boost::weak_ptr<parent> par;//changed from ori blog for the same reason // parent_ptr parent; }; void test() { parent_ptr father(new parent()); children_ptr son(new children()); father->child = son; son->par = father; } int main(void) { std::cout<<"begin test\n"; test(); std::cout<<"end test\n"; return 0; }
I change the code above ref to the stackoverflow doc.
the difference between two of them:
强引用和弱引用
一个强引用当被引用的对象活着的话,这个引用也存在(就是说,当至少有一个强引用,那么这个对象就不能被释放)。boost::share_ptr就是强引用。
相对而言,弱引用当引用的对象活着的时候不一定存在。仅仅是当它存在的时候的一个引用。弱引用并不修改该对象的引用计数,这意味这弱引用它并不对对象的内存进行管理,在功能上类似于普通指针,然而一个比较大的区别是,弱引用能检测到所管理的对象是否已经被释放,从而避免访问非法内存。
the define of 引用计数 may be can ref to some python blog
总结一下对象会在一下情况下引用计数加1:
1.对象被创建:x=4
2.另外的别人被创建:y=x
3.被作为参数传递给函数:foo(x)
4.作为容器对象的一个元素:a=[1,x,'33']
引用计数减少情况
1.一个本地引用离开了它的作用域。比如上面的foo(x)函数结束时,x指向的对象引用减1。
2.对象的别名被显式的销毁:del x ;或者del y
3.对象的一个别名被赋值给其他对象:x=789
4.对象从一个窗口对象中移除:myList.remove(x)
5.窗口对象本身被销毁:del myList,或者窗口对象本身离开了作用域。
As for scoped_ptr:
#include <string.h> #include <iostream> #include <boost/scoped_ptr.hpp> class implementation { public: ~implementation(){std::cout<<"destroying implementation\n";} void do_something(){std::cout<<"did something\n";} }; void test() { boost::scoped_ptr<implementation> impl(new implementation()); impl->do_something(); } int main(void) { std::cout<<"begin\n"; test(); std::cout<<"End\n"; return 0; }
It will automatically destroy when leave.
EOF