auto_ptr智能指针包含在<memory>库中定义,使用auto_ptr智能指针时要#inclde <Memory>头文件。以下代码是auto_ptr智能指针实现的头文件,用模板概念编写,是C++标准库里的一部份。可以学习下如何实现auto_ptr智能指针。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
/** * @brief A simple smart pointer providing strict ownership semantics. * * The Standard says: * <pre> * An @c auto_ptr owns the object it holds a pointer to. Copying * an @c auto_ptr copies the pointer and transfers ownership to the * destination. If more than one @c auto_ptr owns the same object * at the same time the behavior of the program is undefined. * * The uses of @c auto_ptr include providing temporary * exception-safety for dynamically allocated memory, passing * ownership of dynamically allocated memory to a function, and * returning dynamically allocated memory from a function. @c * auto_ptr does not meet the CopyConstructible and Assignable * requirements for Standard Library <a * href="tables.html#65">container</a> elements and thus * instantiating a Standard Library container with an @c auto_ptr * results in undefined behavior. * </pre> * Quoted from [20.4.5]/3. * * Good examples of what can and cannot be done with auto_ptr can * be found in the libstdc++ testsuite. * * @if maint * _GLIBCXX_RESOLVE_LIB_DEFECTS * 127. auto_ptr<> conversion issues * These resolutions have all been incorporated. * @endif */ template<typename _Tp> class auto_ptr { private: _Tp* _M_ptr; public: /// The pointed-to type. typedef _Tp element_type; /** * @brief An %auto_ptr is usually constructed from a raw pointer. * @param p A pointer (defaults to NULL). * * This object now @e owns the object pointed to by @a p. */ explicit auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } /** * @brief An %auto_ptr can be constructed from another %auto_ptr. * @param a Another %auto_ptr of the same type. * * This object now @e owns the object previously owned by @a a, * which has given up ownsership. */ auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { } /** * @brief An %auto_ptr can be constructed from another %auto_ptr. * @param a Another %auto_ptr of a different but related type. * * A pointer-to-Tp1 must be convertible to a * pointer-to-Tp/element_type. * * This object now @e owns the object previously owned by @a a, * which has given up ownsership. */ template<typename _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { } /** * @brief %auto_ptr assignment operator. * @param a Another %auto_ptr of the same type. * * This object now @e owns the object previously owned by @a a, * which has given up ownsership. The object that this one @e * used to own and track has been deleted. */ auto_ptr& operator=(auto_ptr& __a) throw() { reset(__a.release()); return *this; } /** * @brief %auto_ptr assignment operator. * @param a Another %auto_ptr of a different but related type. * * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. * * This object now @e owns the object previously owned by @a a, * which has given up ownsership. The object that this one @e * used to own and track has been deleted. */ template<typename _Tp1> auto_ptr& operator=(auto_ptr<_Tp1>& __a) throw() { reset(__a.release()); return *this; } /** * When the %auto_ptr goes out of scope, the object it owns is * deleted. If it no longer owns anything (i.e., @c get() is * @c NULL), then this has no effect. * * @if maint * The C++ standard says there is supposed to be an empty throw * specification here, but omitting it is standard conforming. Its * presence can be detected only if _Tp::~_Tp() throws, but this is * prohibited. [17.4.3.6]/2 * @end maint */ ~auto_ptr() { delete _M_ptr; } /** * @brief Smart pointer dereferencing. * * If this %auto_ptr no longer owns anything, then this * operation will crash. (For a smart pointer, "no longer owns * anything" is the same as being a null pointer, and you know * what happens when you dereference one of those...) */ element_type& operator*() const throw() { _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); return *_M_ptr; } /** * @brief Smart pointer dereferencing. * * This returns the pointer itself, which the language then will * automatically cause to be dereferenced. */ element_type* operator->() const throw() { _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); return _M_ptr; } /** * @brief Bypassing the smart pointer. * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for * situations such as passing to a function which only accepts * a raw pointer. * * @note This %auto_ptr still owns the memory. */ element_type* get() const throw() { return _M_ptr; } /** * @brief Bypassing the smart pointer. * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for * situations such as passing to a function which only accepts * a raw pointer. * * @note This %auto_ptr no longer owns the memory. When this object * goes out of scope, nothing will happen. */ element_type* release() throw() { element_type* __tmp = _M_ptr; _M_ptr = 0; return __tmp; } /** * @brief Forcibly deletes the managed object. * @param p A pointer (defaults to NULL). * * This object now @e owns the object pointed to by @a p. The * previous object has been deleted. */ void reset(element_type* __p = 0) throw() { if (__p != _M_ptr) { delete _M_ptr; _M_ptr = __p; } } /** @{ * @brief Automatic conversions * * These operations convert an %auto_ptr into and from an auto_ptr_ref * automatically as needed. This allows constructs such as * @code * auto_ptr<Derived> func_returning_auto_ptr(.....); * ... * auto_ptr<Base> ptr = func_returning_auto_ptr(.....); * @endcode */ auto_ptr(auto_ptr_ref<element_type> __ref) throw() : _M_ptr(__ref._M_ptr) { } auto_ptr& operator=(auto_ptr_ref<element_type> __ref) throw() { if (__ref._M_ptr != this->get()) { delete _M_ptr; _M_ptr = __ref._M_ptr; } return *this; } template<typename _Tp1> operator auto_ptr_ref<_Tp1>() throw() { return auto_ptr_ref<_Tp1>(this->release()); } template<typename _Tp1> operator auto_ptr<_Tp1>() throw() { return auto_ptr<_Tp1>(this->release()); } /** @} */ }; |
《auto_ptr智能指针头文件》上有2条评论
评论已关闭。