Smart pointers 2

Source: Internet
Author: User
Document directory
  • Class STD: tr1: shared_ptr

 

Class STD: tr1: shared_ptr

ASharted_ptrObject has the ownership of an object if:

  • It was constructed with a pointer to that resource
  • It was constructed fromShared_ptrObject that owns that resource
  • It was constructed fromWeak_ptrObject that points to that resource
  • Ownership of that resource was assigned to it, eitherShared_ptr: Operator =Or by calling the member functionShared_ptr: reset ().

 

All the shared pointer objects that share the ownership of the same resource also shared a control block, containing the number of shared_ptr objects that own the resource, the number of weak_ptr objects that point to the resource, and the deleter (a function used to release the resource), if it has one. an emptyShared_ptrObject does not own any resources and has no control block. On the other hand,Shared_ptrThat was initialized with a null pointer has a control block; this means it is not an empty shared pointer. when the reference counter to a resource becomes 0 (regardless the number of weak pointer still referring the object), the resource is released, either by deleting it or by passing its addresto sed the deleter.

Creating a shared_ptr

There are several constructors available forShared_ptr:

shared_ptr();template<class Other>   explicit shared_ptr(Other*);template<class Other, class D>   shared_ptr(Other*, D);shared_ptr(const shared_ptr&);template<class Other>   shared_ptr(const shared_ptr<Other>&);template<class Other>   shared_ptr(const weak_ptr<Other>&);template<class Other>   shared_ptr(const std::auto_ptr<Other>&);

You basically can create a newShared_ptrFrom:

  • A pointer to any type T (including const T), having the possibility of specifying a deleter for the pointed Resource
  • AnotherShared_ptrObject
  • AWeak_ptrObject
  • AnAuto_ptrObject

The next sample showsShared_ptrCreated fromAuto_ptrObject. The auto pointer gives up the ownership of the resource, resetting its wrapped pointer to null.

int main(){   std::auto_ptr<foo> ap1(new foo);   ap1->print();   std::cout << "ap1 pointer: " << ap1.get() << std::endl;   std::tr1::shared_ptr<foo> sp1(ap1);   sp1->print();   std::cout << "ap1 pointer: " << ap1.get() << std::endl;   std::cout << "sp1 pointer: " << sp1.get() << std::endl;   return 0;}

The output is:

foo::printap1 pointer: 0033A790foo::printap1 pointer: 00000000sp1 pointer: 0033A790

I was saying earlier that, whenShared_ptrObject is created, you can specify a special function called deleter, used to release the resource. If no such function is provided, the resource is simply deleted by calling operator Delete.

Consider, for instance, a case when the creation and deletion of a resource shocould be logged somewhere. for Class Foo defined at the beginning at the article I created a helper class, that creates and destroys instances, but also logs these events.

class foo_handler{public:   static foo* alloc()   {      foo* f = new foo;      ::OutputDebugString(_T("a new foo was created/n"));      return f;   }   static void free(foo* f)   {      delete f;      ::OutputDebugString(_T("foo destroyed/n"));   }};

Each time a new object is created or destroyed, a message is printed in the output window (for simplicity, you will ignore the copy construction or assignment). FunctionFoo_handler: freeCan PE provided as a Delete toShared_ptrConstructor. As a result, when the resource is deleted a message is printed in the output window (You have to run in debugger to see it ).

int main(){   std::tr1::shared_ptr<foo> ptr(      foo_handler::alloc(),      &foo_handler::free);   ptr->print();   return 0;}

Running in debugger and looking into the output window, you can see:

a new foo was createdfoo destroyed

FunctionGet_deleterFrom Header<Memory>Returns a pointer to the deleter ofShared_ptr, If one was provided, or 0 otherwise. the next sample shows how to get the deleter of the shared pointer created earlier.

typedef void (*deleter)(foo*);deleter* del = std::tr1::get_deleter<deleter>(ptr);std::cout << "get_deleter(ptr) != 0 == " << std::boolalpha   << (del != 0) << std::endl;

The output is:

get_deleter(ptr) != 0 == true
Operators-> and * and function get

ClassShared_ptrOverloads operators-> and *, the first returning a pointer to the resource and the second a reference to the value of the resource, so that accessing the internal wrapped pointer is not necessary.

template<class Ty>    class shared_ptr {public:    Ty *get() const;    Ty& operator*() const;    Ty *operator->() const;};

FunctionGet ()Returns the wrapped pointer to the resource (basically identical to operator-> and available for compatibilityAuto_ptr).

   std::tr1::shared_ptr<foo> sp(new foo);   foo* f = sp.get();   if(f) f->print();
Conditional Operator

ClassShared_ptrDefines a bool operator that allows shared pointers to be used in Boolean expressions.Auto_ptr, That is not possible; you have to use function get () to access the internal pointer and check it against null.

void is_empty(std::tr1::shared_ptr<std::string> ptr){   if(ptr)   {      std::cout << "not empty" << std::endl;   }   else   {      std::cout << "is empty" << std::endl;   }}int main(){   std::tr1::shared_ptr<std::string> sp1;   std::tr1::shared_ptr<std::string> sp2(new std::string("demo"));   is_empty(sp1);   is_empty(sp2);   return 0;}

The output is:

is emptynot empty
Swap and assignment

MethodSwap ()And the function with the same name From Header<Memory>Exchange the content of the shared pointers.

int main(){   std::tr1::shared_ptr<std::string> sp1;   std::tr1::shared_ptr<std::string> sp2(new std::string("demo"));   is_empty(sp1);   is_empty(sp2);   sp1.swap(sp2);   is_empty(sp1);   is_empty(sp2);   return 0;}

The output is:

is emptynot emptynot emptyis empty

On the other hand, operator = is overloaded so that a shared pointer can be assigned from anotherShared_ptrOrAuto_ptr.

template<class Ty>    class shared_ptr{public:   shared_ptr& operator=(const shared_ptr&);   template<class Other>      shared_ptr& operator=(const shared_ptr<Other>&);   template<class Other>      shared_ptr& operator=(auto_ptr<Other>&);}

The next sample shows an example of using operator =.

int main(){   std::tr1::shared_ptr<int> sp1(new int(1));   std::cout << "sp1 = " << *sp1 << std::endl;   std::tr1::shared_ptr<int> sp2(new int(2));   std::cout << "sp2 = " << *sp2 << std::endl;   sp1 = sp2;   std::cout << "sp1 = " << *sp1 << std::endl;   return 0;}
Methods unique and use_count

MethodUse_count ()Returns the number of references to the shared resource (pointed by the current shared pointer object). MethodUnique ()Indicates whether another shared pointed shares the ownership of the same resource or not (basically, it's identical to 1 = use_count ()).

int main(){   std::tr1::shared_ptr<std::string>      sp1(new std::string("marius bancila"));   std::cout << "unique : " << std::boolalpha << sp1.unique()             << std::endl;   std::cout << "counter : " << sp1.use_count() << std::endl;   std::tr1::shared_ptr<std::string> sp2(sp1);   std::cout << "unique : " << std::boolalpha << sp1.unique()             << std::endl;   std::cout << "counter : " << sp1.use_count() << std::endl;   return 0;}

The output is:

unique : truecounter : 1unique : falsecounter : 2
Resetting

FunctionReset ()Decrements the shared reference counter. It then transforms the shared pointer to an emptyShared_ptr.

int main(){   // a shared_ptr owns the resouce, counter is 1   std::tr1::shared_ptr<foo> sp1(new foo);   std::cout << "counter sp1: " << sp1.use_count() << std::endl;   // a second shared_ptr owns the resourse, shared counter is 2   std::tr1::shared_ptr<foo> sp2(sp1);   std::cout << "counter sp1: " << sp1.use_count() << std::endl;   std::cout << "counter sp2: " << sp2.use_count() << std::endl;   // first shared_ptr is reset, the counter decremented   // and the object becomes empty (no control block anymore)   sp1.reset();   std::cout << "counter sp1: " << sp1.use_count() << std::endl;   std::cout << "counter sp2: " << sp2.use_count() << std::endl;   return 0;}

The output is:

counter sp1: 1counter sp1: 2counter sp2: 2counter sp1: 0counter sp2: 1

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.