- template<class _Tp1> struct auto_ptr_ref {
- _Tp1* _M_ptr;
- auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {}
- };
再看它的构造函数:
- explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
- auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
- #ifdef __STL_MEMBER_TEMPLATES
- template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW
- : _M_ptr(__a.release()) {}
- #endif /* __STL_MEMBER_TEMPLATES */
析构函数:
- ~auto_ptr() { delete _M_ptr; }
- _Tp& operator*() const __STL_NOTHROW {
- return *_M_ptr;
- }
- _Tp* operator->() const __STL_NOTHROW {
- return _M_ptr;
- }
- _Tp* get() const __STL_NOTHROW {
- return _M_ptr;
- }
- _Tp* release() __STL_NOTHROW {
- _Tp* __tmp = _M_ptr;
- _M_ptr = 0;
- return __tmp;
- }
- void reset(_Tp* __p = 0) __STL_NOTHROW {
- if (__p != _M_ptr) {
- delete _M_ptr;
- _M_ptr = __p;
- }
- }
release()释放指针,注意,它并没有释放内存。
reset()重置指针,释放内存并将它指向一个新的对象。它先判断是不是reset到同一对象,否则delete后就会出问题了!
重载的赋值运算符:
- auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW {
- if (&__a != this) {
- delete _M_ptr;
- _M_ptr = __a.release();
- }
- return *this;
- }
- #ifdef __STL_MEMBER_TEMPLATES
- template <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 */
再回头看看它的拷贝构造函数,是的,也防止了多个auto_ptr指向同一个对象,这其实是为了防止在析构的时候多次delete掉同一块内存。因为多次delete掉一个对象在C++是未定义的。
再看看析构函数:它只是delete,并没有将指针置为NULL! 呃,delete NULL好像可以多次,因为C++中定义了它什么都不做。
所以使用auto_ptr一个正确的做法就是这样:auto_ptr
release()中是将指针置为NULL了就是为了防止析构时将对象删掉!
不知道出于什么考虑在析构函数中delete后没有将指针置为NULL?