auto_ptr解析
1 // TEMPLATE CLASS auto_ptr 2 template<class _Ty> 3 class auto_ptr; 4 5 template<class _Ty> 6 struct auto_ptr_ref 7 { // proxy reference for auto_ptr copying 8 explicit auto_ptr_ref(_Ty *_Right) // auto_ptr的引用 [8/8/2017 by whg] 9 : _Ref(_Right) 10 { // construct from generic pointer to auto_ptr ptr 11 } 12 13 _Ty *_Ref; // generic pointer to auto_ptr ptr 14 }; 15 16 template<class _Ty> 17 class auto_ptr 18 { // wrap an object pointer to ensure destruction 19 public: 20 typedef auto_ptr<_Ty> _Myt; // 定义auto_ptr<_Ty>模板类型 [8/8/2017 by whg] 21 typedef _Ty element_type; // 定义模板参数 [8/8/2017 by whg] 22 23 explicit auto_ptr(_Ty *_Ptr = 0) _THROW0() // 构造函数,指针赋值 [8/8/2017 by whg] 24 : _Myptr(_Ptr) 25 { // construct from object pointer 26 } 27 28 auto_ptr(_Myt& _Right) _THROW0() // 构造函数,模板类型赋值 [8/8/2017 by whg] 29 : _Myptr(_Right.release()) // 调用release,返回_Myt指针类型 [8/8/2017 by whg] 30 { // construct by assuming pointer from _Right auto_ptr 31 } 32 33 auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0() // 构造函数,auto_ptr_ref引用赋值 [8/8/2017 by whg] 34 { // construct by assuming pointer from _Right auto_ptr_ref 35 _Ty *_Ptr = _Right._Ref; 36 _Right._Ref = 0; // release old 37 _Myptr = _Ptr; // reset this 38 } 39 40 template<class _Other> 41 operator auto_ptr<_Other>() _THROW0() //强制转换成auto_ptr<_Other>类型 [8/8/2017 by whg] 42 { // convert to compatible auto_ptr 43 return (auto_ptr<_Other>(*this)); 44 } 45 46 template<class _Other> 47 operator auto_ptr_ref<_Other>() _THROW0() // 强制转成auto_ptr_ref<_Other>类型 [8/8/2017 by whg] 48 { // convert to compatible auto_ptr_ref 49 _Other *_Cvtptr = _Myptr; // test implicit conversion 50 auto_ptr_ref<_Other> _Ans(_Cvtptr); 51 _Myptr = 0; // pass ownership to auto_ptr_ref 52 return (_Ans); 53 } 54 55 template<class _Other> 56 _Myt& operator=(auto_ptr<_Other>& _Right) _THROW0() //释放掉_Right的指向内容,然后情况left的指向,改成right的指向 [8/8/2017 by whg] 57 { // assign compatible _Right (assume pointer) 58 reset(_Right.release()); 59 return (*this); 60 } 61 62 template<class _Other> 63 auto_ptr(auto_ptr<_Other>& _Right) _THROW0() // 构造函数,和auto_ptr(_Myt& _Right)差不多? [8/8/2017 by whg] 64 : _Myptr(_Right.release()) 65 { // construct by assuming pointer from _Right 66 } 67 68 _Myt& operator=(_Myt& _Right) _THROW0() // =操作符,先释放掉right,清空left,再赋值给left [8/8/2017 by whg] 69 { // assign compatible _Right (assume pointer) 70 reset(_Right.release()); 71 return (*this); 72 } 73 74 _Myt& operator=(auto_ptr_ref<_Ty> _Right) _THROW0() // 重载=操作符,right为auto_ptr_ref [8/8/2017 by whg] 75 { // assign compatible _Right._Ref (assume pointer) 76 _Ty *_Ptr = _Right._Ref; 77 _Right._Ref = 0; // release old 78 reset(_Ptr); // set new 79 return (*this); 80 } 81 82 ~auto_ptr() _NOEXCEPT //析构函数 [8/8/2017 by whg] 83 { // destroy the object 84 delete _Myptr; 85 } 86 87 _Ty& operator*() const _THROW0() // *操作符,返回指针的实体 [8/8/2017 by whg] 88 { // return designated value 89 #if _ITERATOR_DEBUG_LEVEL == 2 90 if (_Myptr == 0) 91 _DEBUG_ERROR("auto_ptr not dereferencable"); 92 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ 93 94 return (*get()); 95 } 96 97 _Ty *operator->() const _THROW0() // ->操作符,返回指针 [8/8/2017 by whg] 98 { // return pointer to class object 99 #if _ITERATOR_DEBUG_LEVEL == 2 100 if (_Myptr == 0) 101 _DEBUG_ERROR("auto_ptr not dereferencable"); 102 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */ 103 104 return (get()); 105 } 106 107 _Ty *get() const _THROW0() // 返回指针 [8/8/2017 by whg] 108 { // return wrapped pointer 109 return (_Myptr); 110 } 111 112 _Ty *release() _THROW0() // 清空保存的指针 [8/8/2017 by whg] 113 { // return wrapped pointer and give up ownership 114 _Ty *_Tmp = _Myptr; 115 _Myptr = 0; 116 return (_Tmp); 117 } 118 119 void reset(_Ty *_Ptr = 0) // delete先前的内容,然后赋值给新的指针 [8/8/2017 by whg] 120 { // destroy designated object and store new pointer 121 if (_Ptr != _Myptr) 122 delete _Myptr; 123 _Myptr = _Ptr; 124 } 125 126 private: 127 _Ty *_Myptr; // the wrapped object pointer 128 };
release函数返回_Ty*类型指针,会将自身的指针置为0。reset函数会先delete掉自身的指针,然后才接收新的指针。
如果auto_ptr是另一个auto_ptr赋值构造,则必有一个auto_ptr的指针为0。如下所示:
1 class MyClass 2 { 3 public: 4 MyClass(int i){ id =i;}; 5 ~MyClass(){ id = 2;}; 6 int id; 7 }; 8 MyClass* my =new MyClass(1); 9 std::auto_ptr<MyClass> ptr1(my); 10 std::auto_ptr<MyClass> ptr2(ptr1); 11 int id = ptr1->id;
这段代码将在11行crash掉,就是因为构造ptr2会将ptr1内的指针设置为0。生存期结束后,auto_ptr析构函数调用delete释放掉指针0,但不会重复delete。