[置顶] 从源码来看auto_ptr的特性

大家都知道,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的几种运算符操作

这个在代码里面很显然啦,里面部分都有注释哈


你可能感兴趣的:([置顶] 从源码来看auto_ptr的特性)