您的位置:首页 > 其它

auto_ptr解析

2017-08-08 17:48 183 查看

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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: