Shared_ptr of C + + 11 smart pointers

Source: Internet
Author: User



SHARED_PTR is a reference count smart pointer that is used to share ownership of an object. It can be constructed from a bare pointer, another shared_ptr, a auto_ptr, or a weak_ptr. You can also pass the second argument to the constructor of shared_ptr, which is called a delete (deleter). The removal is used to handle the release of shared resources, which is useful for managing resources that are not allocated with new or are not freed with delete. Once the shared_ptr is created, it can be used like a normal pointer, except that it cannot be explicitly deleted. The more important interfaces of shared_ptr are as follows:

Template <class t>

Explicit shared_ptr (t* p);

This constructor gets the ownership of the given pointer p. The parameter p must be a valid pointer to T. The post-construction reference count is set to 1. The only exception thrown from this constructor is Std::bad_alloc (which occurs only in a very rare case, that is, the space required to reference the counter cannot be obtained).

Template <class T,class d>

shared_ptr (t* p,d D);

This constructor has two parameters. The first is the resource that shared_ptr is going to take ownership of, and the second is an object that frees the resources when shared_ptr is destroyed, and the saved resources are passed to that object as D (p). If the reference counter cannot be assigned successfully, shared_ptr throws an exception of type Std::bad_alloc.

shared_ptr (const shared_ptr& R);

The resources saved in R are shared by the newly constructed shared_ptr, and the reference count is added one. This constructor does not throw an exception.

Template <class t>

Explicit shared_ptr (const weak_ptr<t>& R);

Construct shared_ptr from a weak_ptr. This makes the use of weak_ptr thread-safe because the reference count of shared resources pointing to the WEAK_PTR parameter will be self-increasing (weak_ptr does not affect the reference count of shared resources). If weak_ptr is empty (R.use_count () ==0), shared_ptr throws an exception of type bad_weak_ptr.

Template <typename t>

shared_ptr (auto_ptr<t>& R);

This constructor takes ownership of a pointer saved in R from a auto_ptr by saving a copy of the pointer and calling release to Auto_ptr. The constructed reference count is 1, and R becomes empty. If the reference counter cannot be assigned successfully, the Std::bad_alloc is thrown.

~shared_ptr ();

shared_ptr the destructor, minus one for the reference count. If the count is zero, the saved pointer is deleted. The way to delete a pointer is to call operator delete, or, if given a delete object that performs the delete operation, call this object as a unique parameter to the saved pointer. Destructors do not throw exceptions.

shared_ptr& operator= (const shared_ptr& R);

The assignment operation shares resources in R and stops sharing the original resource. An assignment operation does not throw an exception.

void Reset ();

The reset function is used to stop sharing ownership of the saved pointer. The reference count of the shared resource is reduced by one.

t& operator* () const;

This operator returns a reference to the object to which the saved pointer is pointing. If the pointer is empty, calling operator* causes undefined behavior. This operator does not throw an exception.

t* operator-> () const;

This operator returns the saved pointer. This operator, together with operator*, makes the smart pointer look like a normal pointer. This operator does not throw an exception.

t* get () const;

The Get function is the best way to get it when a saved pointer is likely to be empty (at which point both operator* and operator-> cause undefined behavior). Note that you can also use an implicit Boolean type conversion to test whether the shared_ptr contains a valid pointer. This function does not throw an exception.

BOOL Unique () const;

This function returns True if SHARED_PTR is the only owner of the pointer it holds, otherwise false is returned. Unique does not throw an exception.

Long Use_count () const;

The Use_count function returns a reference count of pointers. It is especially useful when debugging because it can get a snapshot of the reference count at key points in the execution of the program. Use it carefully, because in some possible shared_ptr implementations, calculating the reference count can be expensive or even impossible. This function does not throw an exception.

operator Unspecified-bool-type () const;

This is an implicit conversion function to the Unspecified-bool-type type, which can test a smart pointer in a Boolean context. If shared_ptr holds a valid pointer, the return value is true; otherwise false. Note that the type returned by the conversion function is indeterminate. Using the return type as bool can lead to some ridiculous operations, so the typical implementation uses safe bool idiom, which ensures that only applicable Boolean tests are available. This function does not throw an exception.

void Swap (shared_ptr<t>& b);

This makes it easy to exchange two of shared_ptr. The swap function swaps the saved pointers (and their reference counts). This function does not throw an exception.

Template <typename t,typename u> shared_ptr<t> static_pointer_cast (const shared_ptr<u>& R);

To execute static_cast on a pointer held in shared_ptr, we can remove the pointer and cast it, but we cannot save it to another shared_ptr, and the new shared_ptr will consider it to be the first to manage these resources. The workaround is to use Static_pointer_cast, which ensures that the reference count of the object being referred to remains correct. Static_pointer_cast does not throw an exception.

The sample code for using shared_ptr is as follows:



1 {
2 shared_ptr<int> pInt1;
3 Assert (pint1.use_count () = = 0); There are no reference pointers
4 {
5 shared_ptr<int> PInt2 (new int (5));
6 assert (pint2.use_count () = = 1); new Int (5) This pointer is referenced 1 times
7
8 pInt1 = PInt2;
9 Assert (pint2.use_count () = = 2); new Int (5) This pointer is referenced 2 times
ASSERT (pint1.use_count () = = 2);
One}//pint2 out of scope, so the new int (5) is referred to the number of times-1
12
ASSERT (pint1.use_count () = = 1);
+//PInt1 leave scope, number of references-1, now new Int (5) is referenced 0 times, so destroy it


What if the creation of a resource is destroyed not in new and delete ways? You can see from the previous interface that you can specify a shared_ptr constructor. The sample code is as follows:


1 class Filecloser
2 {
3 Public:
4 void operator () (FILE *PF)
5 {
6 if (PF! = NULL)
7 {
8 fclose (PF);
9 PF = NULL;
10}
11}
12};
13
shared_ptr<file> FP (fopen (Pszconfigfile, "R"), Filecloser ());


When using shared_ptr, it is necessary to avoid the same object pointer being treated as a parameter in the Shard_ptr constructor two times. Consider the following code:


1 {
2 int *pint = new int (5);
3 shared_ptr<int> Temp1 (PINT);
4 assert (temp1.use_count () = = 1);
5 shared_ptr<int> Temp2 (PINT);
6 assert (temp2.use_count () = = 1);
7}//Temp1 and Temp2 both leave the scope, they both destroy the pint, causing two times the same memory to be released


The right thing to do is to assign the original pointer to the smart pointer, and the next action is for the smart pointer. The reference code is as follows:
1 {
2 shared_ptr<int> temp1 (new int (5));
3 Assert (temp1.use_count () = = 1);
4 shared_ptr<int> Temp2 (TEMP1);
5 assert (temp2.use_count () = = 2);
6}//Temp1 and Temp2 both leave the scope, the reference count becomes 0, and the pointer is destroyed.

In addition, when you use shared_ptr to wrap this, you also have problems similar to the above. Consider the following code:



1 class A
2 {
3 Public:
4 shared_ptr<a> Get ()
5 {
6 return shared_ptr<a> (this);
7}
8}
9
Shared_ptr<a> PA (New A ());
One shared_ptr<a> PB = Pa->get ();


When PA and Pb leave the scope, the objects on the heap are freed two times. How to solve the above problem? C + + 11 provides a mechanism for deriving a class from the Enable_shared_from_this class and using the Shared_from_this interface when getting shared_ptr. The reference code is as follows:



1 class A:public Enable_shared_from_this<a>
2 {
3 Public:
4 shared_ptr<a> Get ()
5 {
6 return shared_from_this ();
7}
8}


When using shared_ptr in multi-threading, if there is a copy or assignment operation, the count may be invalid due to simultaneous access to the reference count. The workaround is to pass the public week_ptr to each thread, and convert the week_ptr to shared_ptr when the thread needs to use shared_ptr.


Reprint http://www.cnblogs.com/hujian/archive/2012/12/10/2810754.html

If you have copyright issues, please contact QQ 858668791

Shared_ptr of C + + 11 smart pointers

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.