C + + smart pointer unique_ptr
Unique_ptr the object that the exclusive point points to, only one unique_ptr at a time points to the given object (through the prohibition of copy semantics, only the move semantics), defined in memory (non-memory.h), the namespace is Std.
The auto_ptr is defined in earlier versions of the standard library, which has partial characteristics of unique_ptr, but not all, such as the inability to save auto_ptr in a container, or to return auto_ptr from a Function.
For these reasons, you should try to use unique_ptr instead of auto_ptr, and replace auto_ptr with Unique_ptr.
Basic Usage:
Std::unique_ptr<a> up1;
Up1.reset (new A (3));
std::unique_ptr<a> up2 (new A (4));
A * p = up2.release ();
Delete p;
Std::unique_ptr<a> up3 (new A (11));
std::unique_ptr<a> Up4 = Std::move (up3);
Up4 = nullptr;//explicitly destroys the object, while the smart pointer changes to a null Pointer. Equivalent to U_s2.reset ()
member functions
(1) get a pointer to an internal object, because the () method has been overloaded, so it is the same as using the object directly. such as unique_ptr<int> sp (new int (1)); SP is equivalent to Sp.get ()
(2) release discards the ownership of the internal object, resets the internal pointer to null, returns a pointer to the internal object, which needs to be manually disposed
(3) reset destroys the internal object and accepts ownership of the new object (if The default parameter is used, that is, there is no ownership of any objects, only the inner object is freed and set to Null)
(4) swap swap Two shared_ptr objects (that is, objects owned by the clearing House)
Std::move (up) Ownership Transfer (via move semantics), after the up ownership transfer, becomes "null pointer" (up is defined as std::unique_ptr<ty> Up)
UNIQUE_PTR does not support copying and Assignment.
std::unique_ptr<a> up1 (new A (5));
Std::unique_ptr<a> up2 (up1); error, UNIQUE_PTR does not support copying
std::unique_ptr<a> up2 = up1; error, Unique_ptr does not support assignment
Although UNIQUE_PTR does not support copying and assignment, we can call release or reset to transfer ownership of the pointer from one (non-const) unique_ptr to Another.
std::unique_ptr<int> up1 (new int (1));
Std::unique_ptr<int> up2 (up1.release ());
Although Unique_ptr does not support copying, it can be returned from a function or even returned to a local object. As the following code, the compiler knows that the object to be returned is about to be destroyed, so a special "copy" is performed:
Template <class ty>
std::unique_ptr<ty> Clone (const ty& obj)
{
return std::unique_ptr<ty> (new Ty (obj));
}
Template <class ty>
std::unique_ptr<ty> Clone (const ty& obj)
{
std::unique_ptr<ty> temp = std::unique_ptr<ty> (new Ty (obj));
Return temp;
}
UNIQUE_PTR support for managing arrays
std::unique_ptr<a[]> ups (new a[10]);
printf ("sizeof (ups) =%d\n", sizeof (ups));
for (int i = 0; I <; i++)
{
ups[i] = i;
printf ("ups[i] =%d\n", ups[i]);
}
Customizing the Remove Device
The
Overloading a unique_ptr's delete affects the unique_ptr type and how the object of the class is constructed, and the type of the delete must be specified in angle Brackets. then provide a Delete object when creating or Reset.
unique_ptr<t, d> up; The
can use Decltype to indicate the type of the function Pointer.
class Cconnnect { void Disconnect () {print_fun ();} }; void Deleter (cconnnect* obj) { obj// Do other work such as release or disconnect Delete // Delete an object pointer } std::unique_ptr<cconnnect, decltype (deleter) *> up (new cconnnect, deleter) ;
Another way to Use:
class deleter { public: voidoperator() (cconnnect* obj) { Print_fun (); Delete obj; } }; Std::unique_ptr<cconnnect, deleter> up1 (new cconnnect); Std::unique_ptr<cconnnect, deleter> up2 (new cconnnect, up1.get_deleter ());
The realization of source code in VC
template<class_ty,class_dx>//= default_delete<_ty>classunique_ptr: public_unique_ptr_base<_ty, _dx, tr1::is_empty<_Dx>:: Value|| tr1::is_same<default_delete<_ty>, _dx>::value>{ //non-copyable pointer to an object public: typedef unique_ptr<_ty, _dx>_myt; typedef _unique_ptr_base<_ty, _dx, tr1::is_empty<_Dx>:: Value|| tr1::is_same<default_delete<_ty>, _dx>::value>_mybase; typedef typename _MYBASE::P Ointer pointer; typedef _ty element_type; typedef _DX deleter_type; Unique_ptr (): _mybase (pointer (), _dx ()) {//Default ConstructStatic_assert (!is_pointer<_dx>:: value,"unique_ptr constructed with null deleter pointer"); }#ifDefined (_native_nullptr_supported) &&!defined (_do_not_use_nullptr_in_stl) unique_ptr (_std nullptr_t): _mybase (pointer (), _dx ()) {//null pointer constructStatic_assert (!is_pointer<_dx>:: value,"unique_ptr constructed with null deleter pointer"); } _myt&operator=(_std Nullptr_t) {//assign a null pointerReset (); return(* this); }#endif/* defined (_native_nullptr_supported) etc. */Explicitunique_ptr (pointer _ptr): _mybase (_ptr, _dx ()) {//construct with PointerStatic_assert (!is_pointer<_dx>:: value,"unique_ptr constructed with null deleter pointer"); } unique_ptr (pointer _ptr, typename _if<tr1::is_reference<_Dx>:: value, _dx,ConstTypeName Tr1::remove_reference<_dx>::type&>: : _type _dt): _mybase (_ptr, _dt) {//construct with pointer and (maybe Const) deleter&} unique_ptr (pointer _ptr, typename Tr1::remove_reference<_Dx>::type&&_dt): _mybase (_ptr, _std move (_dt)) {//construct by moving deleter//Static_assert (!tr1::is_reference<_dx>::value,//"unique_ptr constructed with reference to Rvalue deleter");} unique_ptr (unique_ptr&&_right): _mybase (_right.release (), _std forward<_Dx>(_right.get_deleter ())) { //construct by moving _right} template<class_ty2,class_dx2>unique_ptr (unique_ptr<_ty2, _dx2>&&_right): _mybase (_right.release (), _std forward<_Dx2>(_right.get_deleter ())) { //construct by moving _right} template<class_ty2,class_dx2>_myt&operator= (unique_ptr<_ty2, _dx2>&&_right) { //assign by moving _rightReset (_right.release ()); this->get_deleter () =_std Move (_right.get_deleter ()); return(* this); } _myt&operator= (_myt&&_right) { //assign by moving _right if( this! = &_right) { //different, do the moveReset (_right.release ()); this->get_deleter () =_std Move (_right.get_deleter ()); } return(* this); } voidSwap (_myt&&_right) { //swap Elements if( this! = &_right) { //different, do the swap_SWAP_ADL ( this-_myptr, _right._myptr); _swap_adl ( this-get_deleter (), _right.get_deleter ()); } } voidSwap (_myt&_right) { //swap Elements_SWAP_ADL ( this-_myptr, _right._myptr); _swap_adl ( this-get_deleter (), _right.get_deleter ()); } ~unique_ptr () {//destroy the object_delete (); } TypeName Tr1::add_reference<_ty>::typeoperator*()Const { //return reference to Object return(* this-_myptr); } pointeroperator()Const { //return pointer to class object return(&** this); } pointerGet()Const { //return pointer to object return( this-_myptr); } _operator_bool ()Const { //test for Non-null Pointer return( this->_myptr! = Pointer ()? _convertible_to_true:0); } pointer release () {//yield ownership of pointerPointer _ans = this-_myptr; this->_myptr =Pointer (); return(_ans); } voidReset (pointer _ptr =Pointer ()) { //Establish new pointer if(_ptr! = this-_myptr) { //different pointer, delete old and reassign_delete (); this->_myptr =_ptr; } }Private: void_delete () {//Delete the pointer if( this->_myptr! =Pointer ()) this->get_deleter () ( this-_myptr); } unique_ptr (Const_myt&);//not definedtemplate<class_ty2,class_dx2>Unique_ptr (Constunique_ptr<_ty2, _dx2>&);//not defined_myt&operator=(Const_myt&);//not definedtemplate<class_ty2,class_dx2>_myt&operator=(Constunique_ptr<_ty2, _dx2>&);//not defined};
C + + smart pointer unique_ptr