通过对VC版本的auto_ptr的源代码得知VC版本还有一点小缺陷,又对VS版本的auto_ptr做了一些剖析,具体代码和注释如下:
1 //假设全局pa2都是用pa1来构造 2 //如:pa2(pa1)、pa2=pa1 3 4 template<class _Ty> //auto_ptr类声明 5 class auto_ptr; 6 7 template<class _Ty> 8 struct auto_ptr_ref //auto_ptr的辅助类 9 { 10 explicit auto_ptr_ref(_Ty *_Right): _Ref(_Right) 11 {} 12 _Ty *_Ref; 13 }; 14 15 template<class _Ty> 16 class auto_ptr//auto_ptr类 17 { 18 public: 19 typedef auto_ptr<_Ty> _Myt; //管理类的类型 20 typedef _Ty element_type; //被管理元素的类型 21 22 explicit auto_ptr(_Ty *_Ptr = 0) : _Myptr(_Ptr) //构造 23 {} //从原始指针中获取控制权 24 25 //若pa2(pa1); 26 auto_ptr(_Myt& _Right) : _Myptr(_Right.release()) //拷贝构造 27 {} 28 29 //若:pa2(pa1) 30 auto_ptr(auto_ptr_ref<_Ty> _Right) 31 { 32 // 用右值来构造 33 _Ty *_Ptr = _Right._Ref; //将pa1的指针保存在Ptr中 34 _Right._Ref = 0; // 将pa1的指针指向空 35 _Myptr = _Ptr; // 将pa2的地址指向pa1的地址 36 } 37 38 template<class _Other> 39 operator auto_ptr<_Other>() //转换为可转换的类型 40 { 41 return (auto_ptr<_Other>(*this)); 42 } 43 44 template<class _Other> 45 operator auto_ptr_ref<_Other>() //隐式类型转换,将auto_ptr类型指针转换为auto_ptr_ref类型 46 { 47 _Other *_Cvtptr = _Myptr; 48 auto_ptr_ref<_Other> _Ans(_Cvtptr); 49 _Myptr = 0; 50 return (_Ans); 51 } 52 53 template<class _Other> 54 _Myt& operator=(auto_ptr<_Other>& _Right) //针对可转换为 _Ty* 类型的 _Other* 类型的拷贝函数 55 { 56 reset(_Right.release()); 57 return (*this); 58 } 59 60 template<class _Other> //特定类型构造函数 61 auto_ptr(auto_ptr<_Other>& _Right) : _Myptr(_Right.release()) 62 {} //针对可转换为 _Ty* 类型的 _Other* 类型的构造函数 63 64 //若:pa2=pa1 65 _Myt& operator=(_Myt& _Right) //拷贝赋值函数 66 { 67 reset(_Right.release()); 68 return (*this); 69 } 70 71 //若:pa2=pa1 72 _Myt& operator=(auto_ptr_ref<_Ty> _Right) //将一个 auto_ptr_ref 类型的变量赋值给 *this 73 { 74 _Ty *_Ptr = _Right._Ref; //将pa1的Ref指针赋值给pa2的_Ptr指针 75 _Right._Ref = 0; // 将pa1的Ref指针指向空 76 reset(_Ptr); // 将pa2的_Myptr指向pa1(pa1已经无拥有权) 77 return (*this); 78 } 79 80 ~auto_ptr() //析构 81 { 82 delete _Myptr; //析构指针所指向的内容 83 } 84 85 _Ty& operator*() const //重载* 86 { 87 if (_Myptr == 0) 88 { 89 _DEBUG_ERROR("auto_ptr not dereferencable"); 90 } 91 return (*get()); 92 } 93 94 _Ty *operator->() const //重载-> 95 { 96 return (get()); 97 } 98 99 _Ty *get() const //用来返回拥有的_Myptr的地址 100 { 101 return (_Myptr); 102 } 103 104 _Ty *release() //将一个对象的_Myptr记住,再指向空,即失去拥有权,然后再把其记住的地址返回 105 { 106 _Ty *_Tmp = _Myptr; //先将pa1的指针用Tmp保存, 107 _Myptr = 0; //再讲pa1的指针指向空,即pa1失去拥有权 108 return (_Tmp); // 返回Tmp即原来pa1指向的地址 109 } 110 111 void reset(_Ty *_Ptr = 0) //将this的_Myptr指向传进来的指针的地址 112 { 113 if (_Ptr != _Myptr) //如果pa1“以前的”(pa1在release()中被指向空,就是返回的那个Tmp用来记住pa1以前的那个地址)那个地址所指向的地址不等于pa2的地址 114 delete _Myptr; //先析构pa2所指向的地址 115 116 _Myptr = _Ptr; //再将pa2地址指向返回来的pa1的老地址 117 } 118 119 private: 120 _Ty *_Myptr; 121 };
测试代码:
1 int main(int argc, char* argv[]) 2 { 3 auto_ptr<int> pa(new int(10)); 4 auto_ptr<int>pa1(pa); 5 cout << *pa1<<endl; 6 auto_ptr<int> pa2; 7 pa2 = pa1; 8 cout << *pa2 << endl; 9 auto_ptr_ref<int> par1(new int(20)); 10 auto_ptr<int> pa3(par1); 11 cout << *pa3 << endl; 12 return 0; 13 }
运行结果:
10
10
20