// 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);
}
};