auto_ptr源码剖析
1 /* 2 * Copyright (c) 1997-1999 3 * Silicon Graphics Computer Systems, Inc. 4 * 5 * Permission to use, copy, modify, distribute and sell this software 6 * and its documentation for any purpose is hereby granted without fee, 7 * provided that the above copyright notice appear in all copies and 8 * that both that copyright notice and this permission notice appear 9 * in supporting documentation. Silicon Graphics makes no 10 * representations about the suitability of this software for any 11 * purpose. It is provided "as is" without express or implied warranty. 12 * 13 */ 14 15 #ifndef __SGI_STL_MEMORY 16 #define __SGI_STL_MEMORY 17 18 #include <stl_algobase.h> 19 #include <stl_alloc.h> 20 #include <stl_construct.h> 21 #include <stl_tempbuf.h> 22 #include <stl_uninitialized.h> 23 #include <stl_raw_storage_iter.h> 24 25 26 __STL_BEGIN_NAMESPACE 27 28 #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \ 29 defined(__STL_MEMBER_TEMPLATES) 30 31 template<class _Tp1> struct auto_ptr_ref { 32 _Tp1* _M_ptr; 33 auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} 34 }; 35 36 #endif 37 38 template <class _Tp> class auto_ptr { 39 private: 40 _Tp* _M_ptr; // 维护一个类型指针 41 42 public: 43 typedef _Tp element_type; 44 45 // 构造函数,初始化所维护的指针 46 explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} 47 48 // 拷贝构造函数,转移控制权,将__a维护的指针转交给当前对象来维护; 49 auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} 50 51 #ifdef __STL_MEMBER_TEMPLATES 52 template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW 53 : _M_ptr(__a.release()) {} 54 #endif /* __STL_MEMBER_TEMPLATES */ 55 56 // 赋值构造函数,重新设定控制权 57 auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { 58 if (&__a != this) { 59 delete _M_ptr; // 解除当前控制权,将所维护的指针所指向的对象析构掉。 60 _M_ptr = __a.release(); // 重新设定控制权,将__a维护的指针转交给当前对象来维护。 61 } 62 return *this; 63 } 64 65 #ifdef __STL_MEMBER_TEMPLATES 66 template <class _Tp1> 67 auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { 68 if (__a.get() != this->get()) { 69 delete _M_ptr; 70 _M_ptr = __a.release(); 71 } 72 return *this; 73 } 74 #endif /* __STL_MEMBER_TEMPLATES */ 75 76 // Note: The C++ standard says there is supposed to be an empty throw 77 // specification here, but omitting it is standard conforming. Its 78 // presence can be detected only if _Tp::~_Tp() throws, but (17.4.3.6/2) 79 // this is prohibited. 80 ~auto_ptr() { delete _M_ptr; } // 析构函数,释放所维护指针指向的资源 81 82 _Tp& operator*() const __STL_NOTHROW { 83 return *_M_ptr; // 重载*操作符,返回对象引用 84 } 85 _Tp* operator->() const __STL_NOTHROW { 86 return _M_ptr; // 重载->操作符,返回对象地址 87 } 88 _Tp* get() const __STL_NOTHROW { 89 return _M_ptr; // 获取所维护指针 90 } 91 _Tp* release() __STL_NOTHROW { 92 _Tp* __tmp = _M_ptr; 93 _M_ptr = 0; // 转移控制权,当前对象不再维护任何指针 94 return __tmp; // 让出控制权 95 } 96 // 重新设定控制权,如果以默认值调用,则释放对象,结束控制权 97 void reset(_Tp* __p = 0) __STL_NOTHROW { 98 if (__p != _M_ptr) { 99 delete _M_ptr; 100 _M_ptr = __p; 101 } 102 } 103 104 // According to the C++ standard, these conversions are required. Most 105 // present-day compilers, however, do not enforce that requirement---and, 106 // in fact, most present-day compilers do not support the language 107 // features that these conversions rely on. 108 109 #if defined(__SGI_STL_USE_AUTO_PTR_CONVERSIONS) && \ 110 defined(__STL_MEMBER_TEMPLATES) 111 112 public: 113 auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW 114 : _M_ptr(__ref._M_ptr) {} 115 116 auto_ptr& operator=(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW { 117 if (__ref._M_ptr != this->get()) { 118 delete _M_ptr; 119 _M_ptr = __ref._M_ptr; 120 } 121 return *this; 122 } 123 124 template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW 125 { return auto_ptr_ref<_Tp1>(this->release()); } 126 template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW 127 { return auto_ptr<_Tp1>(this->release()); } 128 129 #endif /* auto ptr conversions && member templates */ 130 }; 131 132 __STL_END_NAMESPACE 133 134 #endif /* __SGI_STL_MEMORY */ 135 136 137 // Local Variables: 138 // mode:C++ 139 // End: