Program Life >> STL AUTO_PTR smart Pointer Simple analysis: A uto_ptr is a smart pointer inside the STL (Smart Pointer), a good advantage is the automatic transfer of pointer ownership and the automatic pointer removal technology. Useful for exceptions and often forgetting about delete.
Here is the STL auto_ptr from the official SGI website to realize the source code (plus my comments):
/* Copyright (c) 1997-1999 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and Sell this software * and it documentation for any purpose are hereby granted without fee, * provided that the above Copyr ight notice appear in all copies and * that both the copyright notice and this permission notice appear * in supporting D Ocumentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose.
It is provided ' as is ' without express or implied warranty. * */#ifndef __sgi_stl_memory #define __sgi_stl_memory #include <stl_algobase.h> #include <stl_alloc.h> #i Nclude <stl_construct.h> #include <stl_tempbuf.h> #include <stl_uninitialized.h> #include <stl_ Raw_storage_iter.h> __stl_begin_namespace//If AUTO_PTR transformations are defined and support member function templates #if defined (__sgi_stl_use_auto_ptr_ CONVERSIONS) && \ Defined (__stl_member_templates)//define AUTO_PTR_REF template structure ①template<claSS _tp1> struct Auto_ptr_ref {_tp1* _m_ptr;
Auto_ptr_ref (_tp1* __p): _m_ptr (__p) {}};
#endif template <class _tp> class Auto_ptr {private: _tp* _m_ptr;
Public:typedef _TP Element_type; Explicit modifies the constructor to prevent implicit conversion from the original pointer explicit auto_ptr (_tp* __p = 0) __stl_nothrow: _m_ptr (__p) {}//copy constructor, note that this is a direct reference to the parameter (non-CO NST), while transferring pointer ownership auto_ptr (auto_ptr& __a) __stl_nothrow: _m_ptr (__a.release ()) {}//If you are allowed to define member function templates (Member functions Tem Plates) ② #ifdef __stl_member_templates//If you can convert from _tp1* to _tp*, you can construct auto_ptr<_tp1> from auto_ptr<_tp>//
Simultaneous transfer of pointer ownership template <class _tp1> auto_ptr (auto_ptr<_tp1>& __a) __stl_nothrow: _m_ptr (__a.release ()) {} #endif/* __stl_member_templates *//assignment operator, same as non-const reference pass, proven test ③auto_ptr& operator= (auto_ptr& __a) __stl_no
THROW {//If it is self-assigned, return directly if (&__a! = this) {delete _m_ptr;
_m_ptr = __a.release ();
} return *this; } #ifdef the MEMBER Function TEMPLATES T of the __stl_member_templates//assignment operatorEmplate <class _tp1> auto_ptr& operator= (auto_ptr<_tp1>& __a) __stl_nothrow {if (__a.get ()! = This
->get ()) {delete _m_ptr;
_m_ptr = __a.release ();
} return *this; } #endif/* __stl_member_templates *//note:the C + + standard says there are supposed to bes an empty throw//Specifi cation, but omitting it was standard conforming.
IT//presence can detected only if _TP::~_TP () throws, but (17.4.3.6/2)//This is prohibited.
The destructor of Auto_ptr ~auto_ptr () {delete _m_ptr;}
operator* definition, return value _tp& operator* () const __stl_nothrow {return *_m_ptr;
}//operator-> definition, return pointer _tp* operator-> () const __stl_nothrow {return _m_ptr;
}//const member function get definition, return pointer _tp* get () const __stl_nothrow {return _m_ptr;
}//Release function definition, release pointer _tp* release () __stl_nothrow {_tp* __tmp = _m_ptr;
_m_ptr = 0;
return __tmp;
}//Reset function definition, reset pointer void reset (_tp* __p = 0) __stl_nothrow {if (__p! = _m_ptr) {delete _m_ptr; _m_ptr = __p; }}//According to the C + + standard, these conversions is required. Most//present-day compilers, however, don't enforce that requirement---and,//In fact, most present-day compilers D
o The language//features that these conversions rely on. #if defined (__sgi_stl_use_auto_ptr_conversions) && \ defined (__stl_member_templates) public://From Auto_ptr_ref <_Tp> Construction auto_ptr<_tp> auto_ptr (auto_ptr_ref<_tp> __ref) __stl_nothrow: _m_ptr (__ref._m_ptr) {}//from a
Uto_ptr_ref<_tp> an assignment to the auto_ptr<_tp>. Note that this is an ordinary pass, no reference to ④auto_ptr& operator= (auto_ptr_ref<_tp> __ref) __stl_nothrow {if (__ref._m_ptr! = this->
Get ()) {delete _m_ptr;
_m_ptr = __ref._m_ptr;
} return *this;
}//member function template (Member function Templates) ②//If you can convert from _tp* to _tp1*, you can convert from auto_ptr<_tp> to auto_ptr_ref<_tp1> Template <class _tp1> operator auto_ptr_ref<_tp1> () __stl_nothrow {return auto_ptr_ref<_tp1> (This->release ()); }//member function template (Member function Templates) ②//If you can convert from _tp* to _tp1*, you can convert from auto_ptr<_tp> to auto_ptr<_tp1> template &
Lt;class _tp1> operator auto_ptr<_tp1> () __stl_nothrow {return auto_ptr<_tp1> (This->release ());}
#endif/* Auto ptr conversions && member templates */};
__stl_end_namespace #endif/* __sgi_stl_memory *//Local Variables://mode:c++//END:
Annotations:
①auto_ptr_ref Structural Body
We see that the parameters of the copy constructor in the auto_ptr source code are normal reference arguments (not const references, not normal values), which is to facilitate the transfer of pointer ownership (if it is a const reference, then ownership cannot be transferred; if it is a normal value, oh my God , the whole world is completely chaotic). If the copy is constructed with a temporary object (that is, the so-called rvalue), then it cannot be compiled (a normal pointer or reference cannot point to a const object, i.e. it cannot point to the right value). Fortunately, there are auto_ptr_ref, which can be constructed from auto_ptr_ref temporary objects or assigned to AUTO_PTR objects:
Public:
//from auto_ptr_ref<_tp> construction auto_ptr<_tp>
auto_ptr (auto_ptr_ref<_tp> __ref) __STL_ Nothrow
: _m_ptr (__ref._m_ptr) {}
//Auto_ptr<_tp> is assigned from auto_ptr_ref<_tp>.
//Note this is an ordinary pass, no reference to ④
auto_ptr& operator= (auto_ptr_ref<_tp> __ref) __stl_nothrow {
if (__ref._m_ PTR! = This->get ()) {
delete _m_ptr;
_m_ptr = __ref._m_ptr;
}
return *this;
}
The Auto_ptr object can also be implicitly converted to an object of type Auto_ptr_ref:
Template <class _tp1> operator auto_ptr_ref<_tp1> () __stl_nothrow
{return auto_ptr_ref<_tp1> ( This->release ()); }
As a auto_ptr, the transition from Rvalue to Lvalue is completed perfectly. You can also see here: why you need auto_ptr_ref
② member functions Template (Member function Templates)
③ test, see "Effective C + +" clause 11: Handling "Self-assignment" (Item 11) in operator=. Handle assignment to self in operator=)
④ See ①
Original articles, reproduced please specify:
This article is from the program life >> STL auto_ptr smart pointer Simple analysis
Author: Code Maniac