Smart pointer (smart pointer) (2): Unique_ptr

Source: Internet
Author: User

Unique Pointer:
Manages the storage of a pointer, providing a limited garbage-collection facility, with little to no overhead over built-i n Pointers (depending on the deleter used).
These objects has the ability of taking ownership of a pointer:once they take ownership they manage the pointed object B Y becoming responsible for it deletion at some point.
Unique_ptr objects automatically delete the object they manage (using a deleter) as soon as they themselves is destroyed, Or as soon as their value changes either by a assignment operation or by a explicit call to Unique_ptr::reset.
   Unique_ptr objects own their pointer uniquely:no other facility shall take care of deleting the object, and thus no OT She managed pointer should point to its managed object, since as soon as they has to, unique_ptr objects delete their man Aged object without taking into account whether other pointers still point to the same object or not, and thus leaving any Other pointers a there as pointing to a invalid location.

   A Unique_ptr Object has both components:
? A stored pointer:the pointer to the object it manages. This was set on construction, can be altered by anassignment operation or by calling member reset, and can be individually Accessed for reading using members get or release.
? A stored Deleter:a callable object that takes an argument of the same type as the stored pointer and are called to delete The managed object. It is set on construction, can be altered by a assignment operation, and can be individually accessed using member Get_de Leter.

Unique_ptr objects replicate a limited pointer functionality by providing access to its managed object through operators * And, (for individual objects), or operator [] (for array objects). For safety reasons, they don't support pointer arithmetics, and only support move assignment (disabling copy assignments) .

Look at the code:

Template<TypeName_TP,TypeName_tp_deleter = default_delete<_tp> >classunique_ptr { Public:typedef_tp* pointer;typedef_TP Element_type;typedef_tp_deleter Deleter_type;//constructors.Unique_ptr (): _m_t (pointer (), Deleter_type ()) {Static_assert(!STD:: Is_pointer<deleter_type>::value,"Constructed with null function pointer deleter"); }ExplicitUNIQUE_PTR (pointer __p): _m_t (__p, Deleter_type ()) {Static_assert(!STD:: Is_pointer<deleter_type>::value,"Constructed with null function pointer deleter"); } unique_ptr (Pointer __p,TypeName STD::conditional<STD:: Is_reference<deleter_type>::value, Deleter_type,ConstDeleter_type&>::type __d): _m_t (__p, __d) {} unique_ptr (pointer __p,TypeName STD::remove_reference<deleter_type>::type&& __d): _m_t (STD:: Move (__p),STD:: Move (__d)) {Static_assert(!STD:: Is_reference<deleter_type>::value,"Rvalue deleter bound to reference"); }//Move constructors.Unique_ptr (unique_ptr&& __u): _m_t (__u.release (),STD::forward<deleter_type> (__u.get_deleter ())) {}Template<TypeName_UP,TypeName_up_deleter> unique_ptr (unique_ptr<_up, _up_deleter>&& __u): _m_t (__u.release (),STD::forward<deleter_type> (__u.get_deleter ())) {}//destructor.~unique_ptr () {reset ();}//assignment.unique_ptr&operator= (unique_ptr&& __u) {Reset (__u.release ()); Get_deleter () =STD:: Move (__u.get_deleter ());return* This; }Template<TypeName_UP,TypeName_up_deleter> unique_ptr&operator= (unique_ptr<_up, _up_deleter>&& __u) {Reset (__u.release ()); Get_deleter () =STD:: Move (__u.get_deleter ());return* This; } unique_ptr&operator= (__unspecified_pointer_type) {reset ();return* This; }//observers.    TypeName STD:: Add_lvalue_reference<element_type>::typeoperator*()Const{_glibcxx_debug_assert (get ()! =0);return*get (); } pointeroperator()Const{_glibcxx_debug_assert (get ()! =0);returnGet (); } pointer get ()Const{return STD::get<0> (_m_t); }TypeName STD:: Add_lvalue_reference<deleter_type>::type get_deleter () {return STD::get<1> (_m_t); }TypeName STD::add_lvalue_reference<TypeName STD:: Add_const<deleter_type>::type >::type Get_deleter ()Const{return STD::get<1> (_m_t); }operator__unspecified_bool_type ()Const{returnGet () = =0?0: &unique_ptr::_M_t; }//Modifiers.Pointer release () {pointer __p = get ();STD::get<0> (_m_t) =0;return__p; }voidReset (pointer __p = pointer ()) {if(__p! = Get ()) {Get_deleter () (Get ());STD::get<0> (_m_t) = __p; }    }voidSwap (unique_ptr&& __u) {using STD:: Swap;    Swap (_m_t, __u._m_t); }//Disable copy from Lvalue.Unique_ptr (Constunique_ptr&) =Delete;Template<TypeName_UP,TypeName_up_deleter> Unique_ptr (ConstUNIQUE_PTR&LT;_UP, _up_deleter>&) =Delete; unique_ptr&operator=(Constunique_ptr&) =Delete;Template<TypeName_UP,TypeName_up_deleter> unique_ptr&operator=(ConstUNIQUE_PTR&LT;_UP, _up_deleter>&) =Delete;Private: __tuple_type _m_t;};

The above code disables copy construction and assignment operations, so you must emphasize the use of move semantics or rvalue references when you use them, or you will get an error.

Summary:
UNIQUE_PTR is a proprietary smart pointer that provides a strict semantic ownership, including:
1. Have the object it points to.
2. Cannot make copy construction or copy assignment operation. In other words, we cannot get two unique_ptr that point to the same object. However, you can move the construction and move assignment operations.
3. A pointer to an object is saved, and when it is deleted (for example, out of a scope), the object it points to is freed with the given delete.
With Unique_ptr, you can implement the following features, including:
1, for the dynamic application of memory to provide exception security.
2. Transfer the ownership of the dynamic request memory to a function.
3. Return the ownership of the dynamic request memory from a function.
4. Save the pointer in the container.
5. Features that all auto_ptr should have (but not implemented in C + + 03)
As for the unique_ptr and auto_ptr differences are mainly semantically, and in the case of the need to exchange control (not the right value), Unique_ptr will explicitly ask for a move operation, otherwise it will alert the user, which avoids some unintentional copy occurrence. The second difference is that unique_ptr is more efficient because he uses rvalue references rather than copy constructs.
The Auto_ptr destructor simply deletes the raw pointer, and UNIQUE_PTR can customize its own deleter to specify what needs to be done when the unique_ptr is refactored.

//Unique_ptr destructor Example#include <iostream>#include <memory>intMain () {AutoDeleter = [] (int*P) {DeletePSTD::cout<<"[Deleter called]\n"; };STD::unique_ptr<int,Decltype(deleter) > foo (New int, deleter);STD::cout<<"foo"<< (foo?)" is not":"is") <<"empty\n";return 0;//[deleter called]}output:foo is not empty[deleter called]

The move semantics introduced in c++11 enable UNIQUE_PTR to be stored in the container, as referenced in this article (http://www.th7.cn/Program/cp/201408/267890.shtml). Using move means discarding ownership of the object, but does not release the raw pointer. After the move function is called, it loses ownership of the raw pointer, does not release the raw pointer, and then, if the original unique_ptr is misused, causes undefine behavior.

Smart pointer (smart pointer) (2): Unique_ptr

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.