1.auto_ptr

auto_ptr简介

auto_ptr一个对象只有一个拥有者(一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象)


注:

对于智能指针可以参看《Beyond the C++ Standard Library:An Introduction to Boost》、

《boost_1_41_0_doc》地址:http://code.google.com/p/boost-doc-zh/ ,都很给力

在c++11标准中auto_ptr被废弃了。。引入了shared_ptr和unique_ptr

不过还是在很多的场所可以使用,先来看一看

auto_ptr的设计动机

1.程序忘记释放申请的资源
2.异常而没有正确释放申请的资源
eg:
	//一般版本
  void fun()
    {
      try
      {
        T *ptr = new T;
        ......
      }catch(...)
      {
        delete ptr;
        throw;
      }
      delete ptr;
    }
	//auto_ptr版本
  void fun()
    {
      auto_ptr<T> ptr(new T);
      ......
    }
//From vs2010 memory
//
// include auto_ptr shared_ptr weak_ptr unique_ptr in vs2010
//
// TEMPLATE CLASS auto_ptr
template<class _Ty>
	class auto_ptr;

template<class _Ty>
	struct auto_ptr_ref
		{	// proxy reference for auto_ptr copying 使我们可以拷贝和赋值临时的右值auto_ptr,在下面的auto_ptr构造函数中使用
	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 auto_ptr<_Ty> _Myt;
	typedef _Ty element_type;

	explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
		: _Myptr(_Ptr)
		{	// construct from object pointer
		}

	auto_ptr(_Myt& _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
		}

	template<class _Other>
		operator auto_ptr<_Other>() _THROW0()
		{	// convert to compatible auto_ptr
		return (auto_ptr<_Other>(*this));
		}

	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>
		_Myt& 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
		}

	_Myt& operator=(_Myt& _Right) _THROW0()
		{	// assign compatible _Right (assume pointer)
		reset(_Right.release());
		return (*this);
		}

	_Myt& 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
		delete _Myptr;
		}

	_Ty& operator*() const _THROW0()
		{	// return designated value
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Myptr == 0)
			_DEBUG_ERROR("auto_ptr not dereferencable");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		return (*get());
		}

	_Ty *operator->() const _THROW0()
		{	// return pointer to class object
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Myptr == 0)
			_DEBUG_ERROR("auto_ptr not dereferencable");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		return (get());
		}

	_Ty *get() const _THROW0()
		{	// return wrapped pointer
		return (_Myptr);
		}

	_Ty *release() _THROW0()
		{	// return wrapped pointer and give up ownership
		_Ty *_Tmp = _Myptr;
		_Myptr = 0;
		return (_Tmp);
		}

	void reset(_Ty *_Ptr = 0)
		{	// destroy designated object and store new pointer
		if (_Ptr != _Myptr)
			delete _Myptr;
		_Myptr = _Ptr;
		}

private:
	_Ty *_Myptr;	// the wrapped object pointer
	};

auto_ptr复制控制函数的特点

auto_ptr的复制构造函数和赋值操作符都很bt,会把所有权挪给新对象,同时原对象置为0,详见上面的源码

eg:
//只能使用显式构造函数,因为auto_ptr_ref使得临时对象可以被构造
//通过auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()把auto_ptr<int>(new int(0))转换成auto_ptr_ref<T>
//发现类型转换函数operator auto_ptr_ref<Y>() throw()从而转换成auto_ptr<int>
auto_ptr<int> pi1(new int(100));
auto_ptr<int> pi2(pi1);//pi1的所有权给了pi2,pi1为nullptr,pi2现在当然于pi1了,但不能对pi1解引用了
//auto_ptr<int> pi2=pi1;

auto_ptr的使用规则

1.auto_ptr不能指向数组,因为在auto_ptr中析构函数用的是delete而不是delete[],详见源码
2.auto_ptr不能被用在stl标准容器中,auto_ptr不具有值语义(比如== !=),因为源码中都没有重载这些操作符
3.较为隐蔽的情形:
将auto_ptr作为函数参数按值传递,因为在函数调用过程中在函数的作用域中会产生一个局部对象来接收传入的auto_ptr拷贝构造,这样,传入的实参auto_ptr就失去了其对原对象的所有权,而该对象会在函数退出时被局部auto_ptr删除。
eg:
  void f(auto_ptr<int> ap){cout<<*ap;}
  auto_ptr<int> ap1(new int(0));
  f(ap1);
  cout<<*ap1; //错误,经过f(ap1)函数调用,ap1已经不再拥有任何对象了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值