auto_prt的VS版本源码剖析

通过对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

上一篇:go读取http.Request中body的内容


下一篇:应用层write调用驱动层write