unique ptr
1 主要代码
1.1 default_delete
/// Primary template of default_delete, used by unique_ptr for single objects
template <typename _Tp>
struct default_delete {
/// Default constructor
constexpr default_delete() noexcept = default;
/** @brief Converting constructor.
*
* Allows conversion from a deleter for objects of another type, `_Up`,
* only if `_Up*` is convertible to `_Tp*`.
*/
template <typename _Up, typename = _Require<is_convertible<_Up*, _Tp*>>>
default_delete(const default_delete<_Up>&) noexcept {
}
/// Calls `delete __ptr`
void operator()(_Tp* __ptr) const {
static_assert(!is_void<_Tp>::value, "can't delete pointer to incomplete type");
static_assert(sizeof(_Tp) > 0, "can't delete pointer to incomplete type");
delete __ptr;
}
};
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length
/// Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
template <typename _Tp>
struct default_delete<_Tp[]> {
public:
/// Default constructor
constexpr default_delete() noexcept = default;
/** @brief Converting constructor.
*
* Allows conversion from a deleter for arrays of another type, such as
* a const-qualified version of `_Tp`.
*
* Conversions from types derived from `_Tp` are not allowed because
* it is undefined to `delete[]` an array of derived types through a
* pointer to the base type.
*/
template <typename _Up, typename = _Require<is_convertible<_Up (*)[], _Tp (*)[]>>>
default_delete(const default_delete<_Up[]>&) noexcept {
}
/// Calls `delete[] __ptr`
template <typename _Up>
typename enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value>::type operator()(_Up* __ptr) const {
static_assert(sizeof(_Tp) > 0, "can't delete pointer to incomplete type");
delete[] __ptr;
}
};
类default_delete
是为unique_ptr
设计的默认的deleter,即当使用者不提供定制的时候,就用这个。对单个对象和数组进行了实现,核心实现就是delete ptr
、delete[] ptr
。
1.2 __uniq_ptr_impl
// Manages the pointer and deleter of a unique_ptr
template <typename _Tp, typename _Dp>
class __uniq_ptr_impl {
template <typename _Up, typename _Ep, typename = void>
struct _Ptr {
using type = _Up*;
};
template <typename _Up, typename _Ep>
struct _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>> {
using type = typename remove_reference<_Ep>::type::pointer;
};
public:
using _DeleterConstraint = enable_if<__and_<__not_<is_pointer<_Dp>>, is_default_constructible<_Dp>>::value>;
using pointer = typename _Ptr<_Tp, _Dp>::type;
static_assert(!is_rvalue_reference<_Dp>::value,
"unique_ptr's deleter type must be a function object type"
" or an lvalue reference type");
__uniq_ptr_impl() = default;
__uniq_ptr_impl(pointer __p) : _M_t() {
_M_ptr() = __p; }
template <typename _Del>
__uniq_ptr_impl(pointer __p, _Del&& __d) : _M_t(__p, std::forward<_Del>(__d)) {
}
__uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept : _M_t(std::move(__u._M_t)) {
__u._M_ptr() = nullptr; }
__uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept {
reset(__u.release());
_M_deleter() = std::forward<_Dp>(__u._M_deleter());
return *this;
}
pointer& _M_ptr() {
return std::get<0>(_M_t);