转自:http://blog.csdn.net/rao_warrior/article/details/8295223
大家都知道,C++的auto_ptr auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理。然而对于auto_ptr来说,它的规则也挺难记,有时候,我也在想,为什么会有这些规则呢,
1) 两个auto_ptr不能同时拥有同一个对象
2) 我们不应该用auto_ptr来管理一个数组指针。
3) auto_ptr赋值运算,应该叫传值,传给别人,自己没有了。
4) auto_ptr的几种隐式转换
5) auto_ptr的几种运算符操作
我相信看看原码,大家都会明白了, 因为在源码面前,没有隐藏
- /*在.../VC/include/memory文件中*/
- #define _THROW0() throw ()
- template<class _Ty>
- struct auto_ptr_ref
- { // proxy reference for auto_ptr copying
- explicit auto_ptr_ref(_Ty *_Right)
- : _Ref(_Right)
- { // construct from generic pointer to auto_ptr ptr
- }
- _Ty *_Ref; // generic pointer to auto_ptr ptr
- };
- template<class _Ty>
- class auto_ptr
- { // wrap an object pointer to ensure destruction
- public:
- typedef _Ty element_type;
- explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
- : _Myptr(_Ptr)
- { // construct from object pointer
- }
- auto_ptr(auto_ptr<_Ty>& _Right) _THROW0()
- : _Myptr(_Right.release())
- { // construct by assuming pointer from _Right auto_ptr
- }
- auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
- { // construct by assuming pointer from _Right auto_ptr_ref
- _Ty *_Ptr = _Right._Ref;
- _Right._Ref = 0; // release old
- _Myptr = _Ptr; // reset this
- }
- /*auto_ptr<_Other>强制转换*/
- template<class _Other>
- operator auto_ptr<_Other>() _THROW0()
- { // convert to compatible auto_ptr
- return (auto_ptr<_Other>(*this));/*调用拷贝构造函数,返回该对象的引用*/
- }
- /*auto_ptr_ref<_Other>强制转换*/
- template<class _Other>
- operator auto_ptr_ref<_Other>() _THROW0()
- { // convert to compatible auto_ptr_ref
- _Other *_Cvtptr = _Myptr; // test implicit conversion
- auto_ptr_ref<_Other> _Ans(_Cvtptr);
- _Myptr = 0; // pass ownership to auto_ptr_ref
- return (_Ans);
- }
- /*重载运算符“=”*/
- template<class _Other>
- auto_ptr<_Ty>& operator=(auto_ptr<_Other>& _Right) _THROW0()
- { // assign compatible _Right (assume pointer)
- reset(_Right.release());
- return (*this);
- }
- /*拷贝构造函数*/
- template<class _Other>
- auto_ptr(auto_ptr<_Other>& _Right) _THROW0()
- : _Myptr(_Right.release())
- { // construct by assuming pointer from _Right
- }
- auto_ptr<_Ty>& operator=(auto_ptr<_Ty>& _Right) _THROW0()
- { // assign compatible _Right (assume pointer)
- reset(_Right.release());
- return (*this);
- }
- auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
- { // assign compatible _Right._Ref (assume pointer)
- _Ty *_Ptr = _Right._Ref;
- _Right._Ref = 0; // release old
- reset(_Ptr); // set new
- return (*this);
- }
- ~auto_ptr()
- { // destroy the object
- if (_Myptr != 0)
- delete _Myptr;
- }
- /*重载"*"运算符*/
- _Ty& operator*() const _THROW0()
- { // return designated value
- #if _HAS_ITERATOR_DEBUGGING
- if (_Myptr == 0)
- _DEBUG_ERROR("auto_ptr not dereferencable");
- #endif /* _HAS_ITERATOR_DEBUGGING */
- __analysis_assume(_Myptr);
- return (*get()); //调用get取_Myptr所指向的数据,相当于*_Myptr
- }
- /*重载"->"运算符*/
- _Ty *operator->() const _THROW0()
- { // return pointer to class object
- #if _HAS_ITERATOR_DEBUGGING
- if (_Myptr == 0)
- _DEBUG_ERROR("auto_ptr not dereferencable");
- #endif /* _HAS_ITERATOR_DEBUGGING */
- return (get());//调用get取_Myptr,相当于_Myptr
- }
- _Ty *get() const _THROW0()
- { // return wrapped pointer
- return (_Myptr);
- }
- /*将_Myptr设为0,并返回需要释放的数据*/
- _Ty *release() _THROW0()
- { // return wrapped pointer and give up ownership
- _Ty *_Tmp = _Myptr;
- _Myptr = 0;
- return (_Tmp);
- }
- /*将_Myptr原来内存释放,重置为_Ptr*/
- void reset(_Ty* _Ptr = 0)
- { // destroy designated object and store new pointer
- if (_Ptr != _Myptr && _Myptr != 0)
- delete _Myptr;
- _Myptr = _Ptr;
- }
- private:
- _Ty *_Myptr; // the wrapped object pointer
- };
1)两个auto_ptr不能同时拥有同一个对象
- ~auto_ptr()
- { // destroy the object
- if (_Myptr != 0)
- delete _Myptr;
- }
上面的代码已经能够说明问题了,如果一个对象,两个auto_ptr则会delete 两次,必须出错
2) 我们不应该用auto_ptr来管理一个数组指针。
看看 _Ty *release() _THROW0() ,这个里面都是delete,没有delete []
3) auto_ptr赋值运算,应该叫传值,传给别人,自己没有了。
- /*重载运算符“=”*/
- template<class _Other>
- auto_ptr<_Ty>& operator=(auto_ptr<_Other>& _Right) _THROW0()
- { // assign compatible _Right (assume pointer)
- reset(_Right.release());
- return (*this);
- }
4) auto_ptr的几种隐式转换
operator auto_ptr<_Other>() _THROW0()
operator auto_ptr_ref<_Other>() _THROW0()
那么可以看到做了 auto_ptr<_Other> 、auto_ptr_ref<_Other>的强制转换
5) auto_ptr的几种运算符操作
这个在代码里面很显然啦,里面部分都有注释哈