zoukankan      html  css  js  c++  java
  • auto_ptr解析

    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。

  • 相关阅读:
    sql中别名加as和不加as的区别
    easyui 扩展 datagrid 数据网格视图
    asp.net 版本一键升级,后台直接调用升级脚本
    SQLserver 还原数据库报“指定转换无效”的错的解决方案
    sql视图显示数据不对应
    django channels 实现实时通讯,主动推送
    django orm信号机制 + apschedule 定时任务
    django 使用原始SQL语句方式
    Django model 常用查询(搬运来备份的)
    Python3+ Django2.7开发web排坑记006 apache+wsgi部署应用
  • 原文地址:https://www.cnblogs.com/hgwang/p/7308132.html
Copyright © 2011-2022 走看看