Basic usage of shared_ptr
SHARED_PTR uses reference counting to manage the objects that are pointed. When a new shared_ptr points to the same object (copy shared_ptr, etc.), the reference count plus 1. When shared_ptr leaves the scope, the reference count is reduced by 1. Releases the managed memory when the reference count is 0 o'clock.
The advantage of this is freeing the programmer from the pressure to manually free memory. Before, in order to deal with the exception in the program, it is often necessary to manually encapsulate the pointer into the class, through the destructor to free dynamically allocated memory; Now this process can be handed over to shared_ptr.
Generally we use make_shared to get shared_ptr.
cout<< "Test shared_ptr base usage:" <<endl;
shared_ptr<string> P1 = make_shared<string> ("");
if (P1 && p1->empty ())
*p1 = "Hello";
Auto P2 = make_shared<string> ("World");
cout<<*p1<< ' ' <<*p2<<endl;
cout<< "Test shared_ptr use_count:" <<endl;
cout<< "P1 cnt:" <<p1.use_count () << "\TP2 cnt:" <<p2.use_count () <<endl;
Auto P3 = p2;
cout<< "P1 cnt:" <<p1.use_count () << "\TP2 cnt:" <<p2.use_count () << "\TP3 cnt:" << P3.use_count () <<endl;
P2 = p1;
cout<< "P1 cnt:" <<p1.use_count () << "\TP2 cnt:" <<p2.use_count () << "\TP3 cnt:" << P3.use_count () <<endl;
shared_ptr and New
Shared_ptr can be initialized with a pointer returned by a new expression.
cout<< "Test shared_ptr and New:" <<endl;
shared_ptr<int> P4 (new int (1024));
shared_ptr<int> P5 = new int (1024); Wrong, no implicit constructor
cout<<*p4<<endl;
However, you cannot assign a pointer returned by a new expression to shared_ptr.
In addition, it is particularly noteworthy that you should not mix new and shared_ptr!
void process (shared_ptr<int> ptr)
{
cout<< "in process Use_count:" <<ptr.use_count () < <endl;
}
cout<< "Don ' t mix shared_ptr and Normal pointer:" <<endl;
shared_ptr<int> P5 (new int (1024));
Process (p5);
int v5 = *P5;
cout<< "V5:" <<v5<<endl;
int *P6 = new int (1024);
Process (shared_ptr<int> (P6));
int v6 = *P6;
cout<< "V6:" <<v6<<endl;
The program fragment above will output:
In Process Use_count:2
v5:1024
In Process Use_count:1
v6:0
as you can see, when the second process P6, the shared_ptr reference count is 1, and when you leave the scope of the process, the corresponding memory is released, and P6 becomes the hanging pointer.
So, once the pointer returned by a new expression is managed by shared_ptr, stop accessing the memory through the normal pointer!
Shared_ptr.reset
Shared_ptr can point to another object by resetting it, at which point the reference count of the original object is reduced by one.
cout<< "Test shared_ptr Reset:" <<endl;
cout<< "P1 cnt:" <<p1.use_count () << "\TP2 cnt:" <<p2.use_count () << "\TP3 nt:" << P3.use_count () <<endl;
P1.reset (New string ("Cpp11"));
cout<< "P1 cnt:" <<p1.use_count () << "\TP2 cnt:" <<p2.use_count () << "\TP3 cnt:" << P3.use_count () <<endl;
shared_ptr deleter
You can customize a deleter function to be invoked when the object is released shared_ptr.
void Print_at_delete (int *p)
{
cout<< "deleting ..." <<p<< ' t ' <<*p<<endl;
Delete p;
}
cout<< "Test shared_ptr deleter:" <<endl;
int *P7 = new int (1024);
Shared_ptr<int> P8 (P7, print_at_delete);
P8 = make_shared<int> (1025);
Basic usage of UNIQUE_PTR
Unique_ptr is exclusive to the object being pointed to, as its name shows. Therefore, the unique_ptr can not be copied, assignment, and other operations, but can pass the release function between Unique_ptr transfer control.
cout<< "Test unique_ptr base usage:" <<endl;
Unique_ptr<int> up1 (new int (1024));
cout<< "Up1:" <<*up1<<endl;
Unique_ptr<int> up2 (Up1.release ());
cout<< "up2:" <<*up2<<endl;
Unique_ptr<int> Up3 (UP1); Wrong, unique_ptr can not copy
//up2 = up1;//Wrong, unique_ptr can not copy
unique_ptr<int> up4 (new int (1025));
Up4.reset (Up2.release ());
cout<< "UP4:" <<*up4<<endl;
Unique_ptr as parameters and return values
The above limitations for copying are two special cases where unique_ptr can be used as the return value and parameters of a function, while there is an implied copy, but it is not not.
unique_ptr<int> Clone (int p)
{return
unique_ptr<int> (new Int (p));
}
void Process_unique_ptr (unique_ptr<int> up)
{
cout<< "process unique ptr:" <<*up<< Endl;
}
cout<< "Test unique_ptr parameter and return value:" <<endl;
Auto UP5 = Clone (1024);
cout<< "UP5:" <<*up5<<endl;
Process_unique_ptr (Move (UP5));
cout<< "UP5 after process:" <<*up5<<endl; would cause Segmentfault
Here's the Std::move function, and then separate specific details ^_^
Unique_ptr deleter
Unique_ptr can also set deleter, unlike shared_ptr, it needs to specify the type of deleter in the template parameters. Fortunately we have decltype this sharp weapon, otherwise write up good trouble.
cout<< "Test unique_ptr deleter:" <<endl;
int *P9 = new int (1024);
Unique_ptr<int, Decltype (print_at_delete) *> up6 (P9, print_at_delete);
Unique_ptr<int> UP7 (new int (1025));
Up6.reset (Up7.release ());
Weak_ptr
WEAK_PTR is commonly used in conjunction with shared_ptr. It can point to the object that shared_ptr points to, but does not increase the reference count of the object. This makes it possible for a situation where the object pointed to by Weak_ptr has actually been released. Therefore, WEAK_PTR has a lock function that attempts to retrieve a shared_ptr that points to an object.
cout<< "Test weak_ptr Basic usage:" <<endl;
Auto P10 = make_shared<int> (1024);
Weak_ptr<int> WP1 (p10);
cout<< "P10 use_count:" <<p10.use_count () <<endl;
P10.reset (new int (1025)); This would cause wp1.lock () return a false obj
shared_ptr<int> p11 = Wp1.lock ();
if (p11) cout<< "WP1:" <<*p11<< "Use Count:" <<p11.use_count () <<endl;
Summarize
SHARED_PTR uses reference counting to manage the objects that are pointed.
Shared_ptr can be initialized with a pointer returned by a new expression, but the pointer returned by a new expression cannot be assigned to shared_ptr.
Once the pointer returned by a new expression is managed by shared_ptr, do not access the block of memory through the normal pointer.
Shared_ptr can point to another object by resetting it, at which point the reference count of the original object is reduced by one.
You can customize a deleter function to be invoked when the object is released shared_ptr.
Unique_ptr is exclusive to the object being pointed to.
Unique_ptr can not be copied, assigned, and so on, but you can transfer control between unique_ptr through the release function.
Unique_ptr can be used as the return value and parameters of a function.
Unique_ptr can also set deleter, and you need to specify the type of deleter in the template parameters.
WEAK_PTR is commonly used in conjunction with shared_ptr. It can point to the object that shared_ptr points to, but does not increase the reference count of the object.
WEAK_PTR has a lock function that tries to retrieve a shared_ptr that points to an object.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.