C++:智能指针-TR1的shared_ptr和weak_ptr使用介绍shared_ptr:Basedonareferencecountermodel,withthecounterincrementedeachtimeanewsharedpointerobjectpointstotheresource,anddecrementedwhentheobject'sdestructorexecutes;whenthecountergetsto0,theresourceisreleased.Thispointeriscopyconstructableandassignable;thismakesitusableinSTLcontainers.Moreover,thesharedpointerworkswithpolymorphictypesandincompletetypes.Itsmajordrawbackistheimpossibilitytodetectcyclicdependencies,inwhichcasetheresourcesnevergetreleased(forexample,atreewithnodeshaving(shared)pointerstochildrenbutalsototheparent,inwhichcasetheparentandthechildrenarereferencingeachother,inacycle).Tofixthisissue,asecondsmartpointerwascreated:weak_ptr:Pointstoaresourcereferredbyasharedpointer,butdoesnotparticipateinreferencecounting.Whenthecountersgetsto0,theresourceisreleased,regardlessthenumberofweakpointersreferringit;allthesepointersaremarkedasinvalid.Asharted_ptrobjecthastheownershipofanobjectifItwasconstructedwithapointertothatresource;Itwasconstructedfromashared_ptrobjectthatownsthatresource;Itwasconstructedfromaweak_ptrobjectthatpointstothatresource;Ownershipofthatresourcewasassignedtoit,eitherwithshared_ptr:operator=orbycallingthememberfunctionshared_ptr::reset().Cancreateanewshared_ptrfromApointertoanytypeT(includingconstT),havingthepossibilityofspecifyingadeleterforthepointedresource;Anothershared_ptrobject;Aweak_ptrobject;Anauto_ptrobject;目录[隐藏]11.get()返回对象指针;use_count()返回对象的引用计数22.相比较shared_ptr,auto_ptr在赋值与别人后,是放弃对象引用的。33.在shared_ptr构造函数中,行参指定构造对象和析构对象的函数44.get()返回对象指针,使用-调用成员函数55.get()返回对象指针,if判断是否为null66.swap()交换两个shared_ptr所指向的对象77.使用等号赋值88.unique()判断当前对象的引用计数==1?99.reset()清空当前shared指针,并将所有基于该指针创建的shared指针的引用计数减11010.对引用计数的理解,在容器中使用shared_ptr1111.多态情况下的shared指针使用(声明基类句柄,创建子类对象)1212.dynamic_cast,使用dynamic_pointer_cast将基类向下转型为子类1313.staticcast,使用static_pointer_cast将void转型为char,观察引用计数的变化1414.constcast,如果声明std::tr1::shared_ptrconstintcsp,可以声明std::tr1::shared_ptrintsp=std::tr1::const_pointer_castint(csp);1515.weak_ptr的lock()类似于shared_ptr的get()1616.一个使用shared_ptr和weak_ptr的二叉树数据结构示例[编辑]1.get()返回对象指针;use_count()返回对象的引用计数#includeiostream#includetr1/memoryclassFoo{public:voidprint(){std::coutfoo::printstd::endl;}};/*Whensp2iscreated,sp1incrementsthereferencecounter.*Whenthetwosharedpointerobjectsgetoutofscope,thelast*onethatisdestroyedwillreleasetheresource.**output:*foo::print*sp1pointer:0x90a7008*foo::print*sp1pointer:0x90a7008*sp2pointer:0x90a7008*countersp1:2*countersp2:2*/intmain(){std::tr1::shared_ptrFoosp1(newFoo);sp1-print();std::coutsp1pointer:sp1.get()std::endl;std::tr1::shared_ptrFoosp2(sp1);sp2-print();std::coutsp1pointer:sp1.get()std::endl;std::coutsp2pointer:sp2.get()std::endl;std::coutcountersp1:sp1.use_count()std::endl;std::coutcountersp2:sp2.use_count()std::endl;return0;}[编辑]2.相比较shared_ptr,auto_ptr在赋值与别人后,是放弃对象引用的。#includeiostream#includetr1/memoryclassFoo{public:voidprint(){std::coutfoo::printstd::endl;}};/*Thenextsampleshowsashared_ptrcreatedfromanauto_ptrobject.Theautopointergivesuptheownershipoftheresource,*resettingitswrappedpointertoNULL.**output:*foo::print*ap1pointer:0x99b8008*foo::print*ap1pointer:0*sp1pointer:0x99b8008*/intmain(){std::auto_ptrFooap1(newFoo);ap1-print();std::coutap1pointer:ap1.get()std::endl;std::tr1::shared_ptrFoosp1(ap1);//注意这里是shared_ptrsp1-print();std::coutap1pointer:ap1.get()std::endl;std::coutsp1pointer:sp1.get()std::endl;return0;}[编辑]3.在shared_ptr构造函数中,行参指定构造对象和析构对象的函数#includeiostream#includetr1/memoryclassFoo{public:voidprint(){std::coutfoo::printstd::endl;}};classFooHandler{public:staticFoo*alloc(){Foo*f=newFoo;std::coutanewfoowascreatedstd::endl;returnf;}staticvoidfree(Foo*f){deletef;std::coutfoodestroyedstd::endl;}};/**Eachtimeanewobjectiscreatedordestroyed,amessageisprintedintheoutputwindow(forsimplicity,youwillignorethecopy*constructionorassignment).FunctionFooHandler::freecanbeprovidedasadeletetotheshared_ptrconstructor.Asaresult,*whentheresourceisdeletedamessageisprintedintheoutputwindow(youhavetorunindebuggertoseeit).**output:*anewfoowascreated*foo::print*foodestroyed*/intmain(){std::tr1::shared_ptrFooptr(FooHandler::alloc(),&FooHandler::free);ptr-print();return0;}[编辑]4.get()返回对象指针,使用-调用成员函数#includeiostream#includetr1/memoryclassFoo{public:voidprint(){std::coutfoo::printstd::endl;}};/**Functionget()returnsthewrappedpointertotheresource(basicallyidenticaltooperator-andavailableforcompatibility*withauto_ptr).**output:*foo::print*/intmain(){std::tr1::shared_ptrFoosp(newFoo);Foo*f=sp.get();if(f)f-print();return0;}[编辑]5.get()返回对象指针,if判断是否为null#includeiostream#includetr1/memory/*Classshared_ptrdefinesabooloperatorthatallowssharedpointerstobeusedinbooleanexpressions.*Withauto_ptr,thatisnotpossible;youhavetousefunctionget()toaccesstheinternalpointerandcheckitagainstNULL.*/classPtrUtil{public:staticvoidis_empty(std::tr1::shared_ptrstd::stringptr){if(ptr)std::coutnotemptystd::endl;elsestd::cou