1. shared_ptr: A count pointer, the object being pointed to is deleted at the reference count of 0 o'clock. It represents the ownership of the share (responsible for deleting the object). need to contain <memory>
//definition of the Remove devicestructdeleter{ Public: void operator() (Base *p) {cout<<"[deleter called]"<<Endl; Deletep; }};intMain () {shared_ptr<Base> P1 (NewBase, Deleter ()); {shared_ptr<Base> P2 (p1);//here P1/p2 's Use_count () is 2{shared_ptr<Base> P3 (p2);//here P1/p2/p3 's Use_count () is 3}//P1/p2 's Use_count () becomes 2}//P1 's Use_count () becomes 1P1.reset (); //The non-parametric reset () will make the P1 empty (just like the default construction)//P1 's Use_count () becomes 0 and the above new base is deleted/deconstructed return 0;}
The following usage is incorrect:
//Error 1: Use shared_ptr and manage native pointers yourself. The native pointer is repeated for destructionint*p =New int(9); shared_ptr<int>SP1 (p);Deletep;//Error 2: Multiple shared_ptr are constructed from the same native pointer. The native pointer is repeated for destruction//multiple shared_ptr manage the same native pointer, the subsequent shared_ptr should be directly or indirectly (via WEAK_PTR) from the first constructint*q =New int(Ten); shared_ptr<int>SP2 (q); shared_ptr<int> SP3 (q);
Sometimes it is necessary to get a "point" to the current object's shared_ptr (and then pass it to other functions) in the class's member function. At this point, you only need to inherit enable_shared_from_this, you can use Shared_from_this () in the member function to get to shared_ptr. Example:
classFoo;classbar{ Public: voidTest (shared_ptr<foo>sp);};classFoo: PublicEnable_shared_from_this<foo>{ Public: voidtest (); voidprint ();};voidBar::test (shared_ptr<foo>sp) { //at this point Sp.use_count () is 3SP-print ();}voidfoo::test () {//if replaced with shared_ptr<foo> SP = shared_ptr<foo> (this); Error//this is equivalent to using a native pointer to construct two shared_ptr, which causes the problem of repeated releaseShared_ptr<foo> sp = Shared_from_this ();//at this point Sp.use_count () is 2Bar Bar; Bar.test (SP); //at this point Sp.use_count () is 2}voidFoo::p rint () {cout <<"In Foo::p rint"<<Endl;}intMain () {shared_ptr<Foo> SP1 (NewFoo); SP1-test (); //at this point Sp1.use_count () is 1// !!! Error usage, throw BAD_WEAK_PTR exception!!! //reason (refer to boost's ENABLE_SHARED_FROM_THIS.HPP):Enable_shared_from_this has a member of weak_ptr type, //it can only be assigned by shared_ptr through a member function of Enable_shared_from_this (so the member is empty when using the following method),//Shared_from_this () it is through this member "get" to shared_ptrFoo *FP =NewFoo; FP-test (); DeleteFP;}
2. Weak_ptr:weak shared pointer
intMain () {shared_ptr<int> SP1 (New int(Ten)); //can be constructed with shared_ptr/weak_ptr weak_ptr//weak_ptr has access to resources but no ownership (no increase in reference count)weak_ptr<int> WP (SP1);//WP and SP1 's Use_count () are 1 if(!wp.expired ()) { //Lock (): "Get" an available shared_ptr object from weak_ptrshared_ptr<int> SP2 = WP.Lock();//WP and SP1 's Use_count () are 2*SP2 = -; } //at this time WP and SP1 of the Use_count () are 1 return 0;}
Expired (): Checks whether the Weak_ptr object is invalidated (empty or has no shared_ptr and it observes a resource). As with empty weak_ptr, a failed weak_ptr cannot be used to restore the shared_ptr (lock ()). Expired () and Use_count () ==0 return the same results, but are more efficient. Example:
weak_ptr<int > WP; // at this point wp.expired () is 1 shared_ptr <int > SP1 (new ); WP = sp1;shared_ptr <int > SP2 = WP. lock (); // at this point wp.expired () is 0 sp2.reset (); // at this time wp.expired () is 0 sp1.reset () ; // at this point wp.expired () is 1
In addition,weak_ptr does not overload the * and-operator, and cannot be used like a normal pointer (with the help of Lock (), refer to SP2 in the first example).
SHARED_PTR also has a "ring-referenced" problem, also need to use weak_ptr to circumvent, the following example:
classparent;classchildren; typedef shared_ptr <parent> parent_ptr; // change to typedef weak_ptr<parent> PARENT_PTR to avoid "ring-referenced" problems typedef shared_ptr<children> CHILDREN_PTR; // change to typedef weak_ptr<children> CHILDREN_PTR to avoid "ring-referenced" problems classparent{ Public: Children_ptr Children;};classchildren{ Public: Parent_ptr parent;};intMain () {shared_ptr<parent> father (Newparent); shared_ptr<children> Son (Newchildren); Father-Children =Son; Son-parent = Father;//both father and Son's Use_count () are 2, and the program exits without calling the parent and children destructors!!! return 0;}
3, Unique_ptr:
1) before you get to know Unique_ptr, review the auto_ptr.
Auto_ptr:automatic Pointer ( deprecated since c++11 ).
The Auto_ptr object has ownership of the pointer it manages, which is responsible for its memory release (when it is freed: Auto_ptr object is destroyed).
As with shared_ptr, initializing multiple Auto_ptr objects with the same native pointer results in an error of repeatedly freeing memory.
classbase{ Public: Base () {cout<<"In Base"<<Endl;} ~base () {cout <<"In ~base"<<Endl;} voidTest () {cout <<"In test"<<Endl;}};intMain () {auto_ptr<int> Ap1 (New int); //Basic Operations*ap1 =Ten; int*p = Ap1.Get();//*p = = TenAuto_ptr<base> AP2 (NewBase); AP2-test (); Auto_ptr<Base> ap3 = AP2;//ownership is transferred when assigning or "copying" constructs (it cannot be used in STL containers): Ap2.get () becomes nullAp3test (); Auto_ptr<Base> AP4 (NewBase); Base*BP = Ap4.release ();//ap4.get () becomes null. frees ownership and is no longer responsible for the previously administered pointers (memory). returns the previously managed pointer DeleteBP; Auto_ptr<Base> AP5 (NewBase); Ap5.reset (); //explicitly destroys/destructors the object to which it points. To set a point to a new object return 0;}
Resources:
Http://www.cplusplus.com
Continue to learn in ...
Smart pointers for new features of C++11