智能指针派生类—unique_ptr(STL源码)


// unique_ptr指针(唯一指向资源的指针,每当赋值、构造时,转让右侧指针数据到左侧,右侧为空,即同一时间只有一个指针指向数据)
// 其中,千万别在定义一个unique_ptr指针时出现下述情况已知unique_ptr<int> q(new int(1));q也可以是shared_ptr<int>类型
// unique_ptr<int> p(q.get());这是合法且编译通过(但是就出现了两智能指针指向同一内存的现象),所以当p离开其作用域且q依旧在其作用域范围内时,p的释放导致q为悬空指针,q释放时就会导致重复释放而引起的错误。
// 例如:
std::unique_ptr<int> q(new int(111111));
//std::shared_ptr<int> qq = std::make_shared<int>(2222);
{
	//std::unique_ptr<int> p(q.get());		// 隐含错误:p和q同时指向同一内存,局部变量p离开作用于析构释放内存,导致q成为悬空指针
	//std::unique_ptr<int> pp(qq.get());	// 隐含错误:道理同上
	std::unique_ptr<int> p(q.release());	// .release().q主动放弃内存资源占有权同时置空并返回原指针(ok),shared_ptr没有释放内存且返回原内存指针的函数
}
// TEMPLATE CLASS unique_ptr SCALAR
template<class _Ty,
	class _Dx>	// = default_delete<_Ty>
	class unique_ptr
		: private _Unique_ptr_base<_Ty, _Dx,
			is_empty<_Dx>::value	// 非空 或是 默认删除器 则为true(特化版)
				|| is_same<default_delete<_Ty>, _Dx>::value>
	{	// non-copyable pointer to an object
public:
	typedef unique_ptr<_Ty, _Dx> _Myt;	// 自身类型
	typedef _Unique_ptr_base<_Ty, _Dx,
		is_empty<_Dx>::value
			|| is_same<default_delete<_Ty>, _Dx>::value> _Mybase;// 基类类型
	typedef typename _Mybase::pointer pointer;
	typedef _Ty element_type;
	typedef _Dx deleter_type;

	using _Mybase::get_deleter;// 访问申明

	unique_ptr() _NOEXCEPT
		: _Mybase(pointer())
		{	// default construct
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
		}

	unique_ptr(nullptr_t) _NOEXCEPT
		: _Mybase(pointer())
		{	// null pointer construct
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
		}
	// 不允许指针之间的赋值,但可以赋值为0
	_Myt& operator=(nullptr_t) _NOEXCEPT
		{	// assign a null pointer
		reset();// 释放资源
		return (*this);
		}

	explicit unique_ptr(pointer _Ptr) _NOEXCEPT
		: _Mybase(_Ptr)
		{	// construct with pointer
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
		}

	unique_ptr(pointer _Ptr,
		typename _If<is_reference<_Dx>::value, _Dx,
			const typename remove_reference<_Dx>::type&>::type _Dt) _NOEXCEPT
		: _Mybase(_Ptr, _Dt)
		{	// construct with pointer and (maybe const) deleter&
		}

	unique_ptr(pointer _Ptr,
		typename remove_reference<_Dx>::type&& _Dt) _NOEXCEPT
		: _Mybase(_Ptr, _STD move(_Dt))
		{	// construct by moving deleter
		static_assert(!is_reference<_Dx>::value,
			"unique_ptr constructed with reference to rvalue deleter");
		}
	// 移动copy
	unique_ptr(unique_ptr&& _Right) _NOEXCEPT
		: _Mybase(_Right.release(),// 释放右侧无名对象
			_STD forward<_Dx>(_Right.get_deleter()))
		{	// construct by moving _Right
		}

	template<class _Ty2,
		class _Dx2,
		class = typename enable_if<!is_array<_Ty2>::value
			&& is_convertible<typename unique_ptr<_Ty2, _Dx2>::pointer,
				pointer>::value
			&& ((is_reference<_Dx>::value && is_same<_Dx, _Dx2>::value)
				|| (!is_reference<_Dx>::value
					&& is_convertible<_Dx2, _Dx>::value)),
			void>::type>
		unique_ptr(unique_ptr<_Ty2, _Dx2>&& _Right) _NOEXCEPT
			: _Mybase(_Right.release(),
				_STD forward<_Dx2>(_Right.get_deleter()))
		{	// construct by moving _Right
		}

	template<class _Ty2,
		class = typename enable_if<is_convertible<_Ty2 *, _Ty *>::value
			&& is_same<_Dx, default_delete<_Ty> >::value,
			void>::type>
		unique_ptr(auto_ptr<_Ty2>&& _Right) _NOEXCEPT
			: _Mybase(_Right.release())
		{	// construct by moving _Right
		}

	template<class _Ty2,
		class _Dx2>
		typename enable_if<!is_array<_Ty2>::value
			&& is_convertible<typename unique_ptr<_Ty2, _Dx2>::pointer,
				pointer>::value,
			_Myt&>::type
		operator=(unique_ptr<_Ty2, _Dx2>&& _Right) _NOEXCEPT
		{	// assign by moving _Right
		reset(_Right.release());
		this->get_deleter() = _STD forward<_Dx2>(_Right.get_deleter());
		return (*this);
		}
	// 移动赋值
	_Myt& operator=(_Myt&& _Right) _NOEXCEPT
		{	// assign by moving _Right
		if (this != &_Right)
			{	// different, do the move
			reset(_Right.release());
			this->get_deleter() = _STD forward<_Dx>(_Right.get_deleter());
			}
		return (*this);
		}

	void swap(_Myt& _Right) _NOEXCEPT
		{	// swap elements
		_Swap_adl(this->_Myptr, _Right._Myptr);
		_Swap_adl(this->get_deleter(),
			_Right.get_deleter());
		}

	~unique_ptr() _NOEXCEPT
		{	// destroy the object
		if (this->_Myptr != pointer())
			this->get_deleter()(this->_Myptr);// 析构,调用删除器函数对象释放资源
		}

	typename add_reference<_Ty>::type operator*() const
		{	// return reference to object
		return (*this->_Myptr);
		}

	pointer operator->() const _NOEXCEPT
		{	// return pointer to class object
		return (_STD pointer_traits<pointer>::pointer_to(**this));
		}

	pointer get() const _NOEXCEPT
		{	// return pointer to object
		return (this->_Myptr);
		}

	explicit operator bool() const _NOEXCEPT
		{	// test for non-null pointer
		return (this->_Myptr != pointer());
		}
	// 放弃对资源的控制,返回资源指针
	pointer release() _NOEXCEPT
		{	// yield ownership of pointer
		pointer _Ans = this->_Myptr;
		this->_Myptr = pointer();
		return (_Ans);
		}
	// 建立新的指针数据,释放old指针数据
	void reset(pointer _Ptr = pointer()) _NOEXCEPT
		{	// establish new pointer
		pointer _Old = this->_Myptr;
		this->_Myptr = _Ptr;
		if (_Old != pointer())
			this->get_deleter()(_Old);
		}
	// 定义为delete,不允许copy构造和赋值构造
	unique_ptr(const _Myt&) = delete;
	_Myt& operator=(const _Myt&) = delete;
	};







// TEMPLATE CLASS unique_ptr ARRAY
// 指针数组模板类
template<class _Ty,
	class _Dx>
	class unique_ptr<_Ty[], _Dx>
		: private _Unique_ptr_base<_Ty, _Dx,
			is_empty<_Dx>::value
				|| is_same<default_delete<_Ty[]>, _Dx>::value>
	{	// non-copyable pointer to an array object
public:
	typedef unique_ptr<_Ty[], _Dx> _Myt;
	typedef _Unique_ptr_base<_Ty, _Dx,
		is_empty<_Dx>::value
			|| is_same<default_delete<_Ty[]>, _Dx>::value> _Mybase;
	typedef typename _Mybase::pointer pointer;
	typedef _Ty element_type;
	typedef _Dx deleter_type;

	using _Mybase::get_deleter;

	unique_ptr() _NOEXCEPT
		: _Mybase(pointer())
		{	// default construct
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
		}

	explicit unique_ptr(pointer _Ptr) _NOEXCEPT
		: _Mybase(_Ptr)
		{	// construct with pointer
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
		}

	unique_ptr(pointer _Ptr,
		typename _If<is_reference<_Dx>::value, _Dx,
			const typename remove_reference<_Dx>::type&>::type _Dt) _NOEXCEPT
		: _Mybase(_Ptr, _Dt)
		{	// construct with pointer and (maybe const) deleter&
		}

	unique_ptr(pointer _Ptr,
		typename remove_reference<_Dx>::type&& _Dt) _NOEXCEPT
		: _Mybase(_Ptr, _STD move(_Dt))
		{	// construct by moving deleter
		static_assert(!is_reference<_Dx>::value,
			"unique_ptr constructed with reference to rvalue deleter");
		}

	unique_ptr(unique_ptr&& _Right) _NOEXCEPT
		: _Mybase(_Right.release(),
			_STD forward<_Dx>(_Right.get_deleter()))
		{	// construct by moving _Right
		}

	_Myt& operator=(_Myt&& _Right) _NOEXCEPT
		{	// assign by moving _Right
		if (this != &_Right)
			{	// different, do the swap
			reset(_Right.release());
			this->get_deleter() = _STD move(_Right.get_deleter());
			}
		return (*this);
		}

	unique_ptr(nullptr_t) _NOEXCEPT
		: _Mybase(pointer())
		{	// null pointer construct
		static_assert(!is_pointer<_Dx>::value,
			"unique_ptr constructed with null deleter pointer");
		}

	_Myt& operator=(nullptr_t) _NOEXCEPT
		{	// assign a null pointer
		reset();
		return (*this);
		}

	void reset(nullptr_t) _NOEXCEPT
		{	// establish new null pointer
		reset();
		}

	void swap(_Myt& _Right) _NOEXCEPT
		{	// swap elements
		_Swap_adl(this->_Myptr, _Right._Myptr);
		_Swap_adl(this->get_deleter(), _Right.get_deleter());
		}

	~unique_ptr() _NOEXCEPT
		{	// destroy the object
		_Delete();
		}

	// 重载[]
	typename add_reference<_Ty>::type operator[](size_t _Idx) const
		{	// return reference to object
		return (this->_Myptr[_Idx]);
		}

	pointer get() const _NOEXCEPT
		{	// return pointer to object
		return (this->_Myptr);
		}

	explicit operator bool() const _NOEXCEPT
		{	// test for non-null pointer
		return (this->_Myptr != pointer());
		}

	pointer release() _NOEXCEPT
		{	// yield ownership of pointer
		pointer _Ans = this->_Myptr;
		this->_Myptr = pointer();
		return (_Ans);
		}

	void reset(pointer _Ptr = pointer()) _NOEXCEPT
		{	// establish new pointer
		_Delete();
		this->_Myptr = _Ptr;
		}

	template<class _Ptr2>
		explicit unique_ptr(_Ptr2) = delete;

	template<class _Ptr2,
		class _Dx2>
		unique_ptr(_Ptr2, _Dx2) = delete;

	unique_ptr(const _Myt&) = delete;

	_Myt& operator=(const _Myt&) = delete;

	template<class _Ptr2>
		void reset(_Ptr2) = delete;

private:
	void _Delete()
		{	// delete the pointer
		if (this->_Myptr != pointer())
			this->get_deleter()(this->_Myptr);
		}
	};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值