auto_ptr解析

Posted 炽离

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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。

 

以上是关于auto_ptr解析的主要内容,如果未能解决你的问题,请参考以下文章

C++的智能指针auto_ptrunqiue_ptr源码解析

片段(Java) | 机试题+算法思路+考点+代码解析 2023

智能指针之 auto_ptr

auto_ptr 的动态内存分配

c++11 auto_ptr介绍

scoped _ptr的模拟实现与解析