zoukankan      html  css  js  c++  java
  • 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
     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的指针指向空
    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

  • 相关阅读:
    电子书下载:Pro jQuery
    神鬼传奇小技巧:教你如何修改自己想要的时装
    用虚拟机玩游戏的方法!! 开3D加速!
    如何让DevExpress的DateEdit控件正确显示日期的周名
    SOAP Version 1.2
    Delphi中的容器类
    <神鬼传奇>客户端终极优化精简方法
    今日阅读20090102基本数据结构
    判断一个char[]里是否包含两个连续的\r\n
    蛙蛙推荐:改进同步等待的网络服务端应用
  • 原文地址:https://www.cnblogs.com/WindSun/p/10421292.html
Copyright © 2011-2022 走看看