c++新特性11 (10)shared_ptr八”shared_ptr类“
Posted thefist11
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++新特性11 (10)shared_ptr八”shared_ptr类“相关的知识,希望对你有一定的参考价值。
template <class _Ty>
class shared_ptr : public _Ptr_base<_Ty> // class for reference counted resource management
private:
constexpr shared_ptr() noexcept = default;
constexpr shared_ptr(nullptr_t) noexcept // construct empty shared_ptr
template <class _Ux,
enable_if_t<conjunction_v<conditional_t<is_array_v<_Ty>, _Can_array_delete<_Ux>, _Can_scalar_delete<_Ux>>,
_SP_convertible<_Ux, _Ty>>,
int> = 0>
explicit shared_ptr(_Ux* _Px) // construct shared_ptr object that owns _Px
if constexpr (is_array_v<_Ty>)
_Setpd(_Px, default_delete<_Ux[]>);
else
_Temporary_owner<_Ux> _Owner(_Px);
_Set_ptr_rep_and_enable_shared(_Owner._Ptr, new _Ref_count<_Ux>(_Owner._Ptr));
_Owner._Ptr = nullptr;
template <class _Ux, class _Dx,
enable_if_t<conjunction_v<is_move_constructible<_Dx>, _Can_call_function_object<_Dx&, _Ux*&>,
_SP_convertible<_Ux, _Ty>>,
int> = 0>
shared_ptr(_Ux* _Px, _Dx _Dt) // construct with _Px, deleter
_Setpd(_Px, _STD move(_Dt));
template <class _Ux, class _Dx, class _Alloc,
enable_if_t<conjunction_v<is_move_constructible<_Dx>, _Can_call_function_object<_Dx&, _Ux*&>,
_SP_convertible<_Ux, _Ty>>,
int> = 0>
shared_ptr(_Ux* _Px, _Dx _Dt, _Alloc _Ax) // construct with _Px, deleter, allocator
_Setpda(_Px, _STD move(_Dt), _Ax);
template <class _Dx,
enable_if_t<conjunction_v<is_move_constructible<_Dx>, _Can_call_function_object<_Dx&, nullptr_t&>>, int> = 0>
shared_ptr(nullptr_t, _Dx _Dt) // construct with nullptr, deleter
_Setpd(nullptr, _STD move(_Dt));
template <class _Dx, class _Alloc,
enable_if_t<conjunction_v<is_move_constructible<_Dx>, _Can_call_function_object<_Dx&, nullptr_t&>>, int> = 0>
shared_ptr(nullptr_t, _Dx _Dt, _Alloc _Ax) // construct with nullptr, deleter, allocator
_Setpda(nullptr, _STD move(_Dt), _Ax);
template <class _Ty2>
shared_ptr(const shared_ptr<_Ty2>& _Right, element_type* _Px) noexcept
// construct shared_ptr object that aliases _Right
this->_Alias_construct_from(_Right, _Px);
template <class _Ty2>
shared_ptr(shared_ptr<_Ty2>&& _Right, element_type* _Px) noexcept
// move construct shared_ptr object that aliases _Right
this->_Alias_move_construct_from(_STD move(_Right), _Px);
shared_ptr(const shared_ptr& _Other) noexcept // construct shared_ptr object that owns same resource as _Other
this->_Copy_construct_from(_Other);
template <class _Ty2, enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
shared_ptr(const shared_ptr<_Ty2>& _Other) noexcept
// construct shared_ptr object that owns same resource as _Other
this->_Copy_construct_from(_Other);
shared_ptr(shared_ptr&& _Right) noexcept // construct shared_ptr object that takes resource from _Right
this->_Move_construct_from(_STD move(_Right));
template <class _Ty2, enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
shared_ptr(shared_ptr<_Ty2>&& _Right) noexcept // construct shared_ptr object that takes resource from _Right
this->_Move_construct_from(_STD move(_Right));
template <class _Ty2, enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
explicit shared_ptr(const weak_ptr<_Ty2>& _Other) // construct shared_ptr object that owns resource *_Other
if (!this->_Construct_from_weak(_Other))
_Throw_bad_weak_ptr();
template <class _Ux, class _Dx,
enable_if_t<conjunction_v<_SP_pointer_compatible<_Ux, _Ty>,
is_convertible<typename unique_ptr<_Ux, _Dx>::pointer, element_type*>>,
int> = 0>
shared_ptr(unique_ptr<_Ux, _Dx>&& _Other)
using _Fancy_t = typename unique_ptr<_Ux, _Dx>::pointer;
using _Raw_t = typename unique_ptr<_Ux, _Dx>::element_type*;
using _Deleter_t = conditional_t<is_reference_v<_Dx>, decltype(_STD ref(_Other.get_deleter())), _Dx>;
const _Fancy_t _Fancy = _Other.get();
if (_Fancy)
const _Raw_t _Raw = _Fancy;
const auto _Rx = new _Ref_count_resource<_Fancy_t, _Deleter_t>(_Fancy, _Other.get_deleter());
_Set_ptr_rep_and_enable_shared(_Raw, _Rx);
_Other.release();
~shared_ptr() noexcept // release resource
this->_Decref();
shared_ptr& operator=(const shared_ptr& _Right) noexcept
shared_ptr(_Right).swap(*this);
return *this;
template <class _Ty2>
shared_ptr& operator=(const shared_ptr<_Ty2>& _Right) noexcept
shared_ptr(_Right).swap(*this);
return *this;
shared_ptr& operator=(shared_ptr&& _Right) noexcept // take resource from _Right
shared_ptr(_STD move(_Right)).swap(*this);
return *this;
template <class _Ty2>
shared_ptr& operator=(shared_ptr<_Ty2>&& _Right) noexcept // take resource from _Right
shared_ptr(_STD move(_Right)).swap(*this);
return *this;
template <class _Ux, class _Dx>
shared_ptr& operator=(unique_ptr<_Ux, _Dx>&& _Right) // move from unique_ptr
shared_ptr(_STD move(_Right)).swap(*this);
return *this;
void swap(shared_ptr& _Other) noexcept
this->_Swap(_Other);
void reset() noexcept // release resource and convert to empty shared_ptr object
shared_ptr().swap(*this);
template <class _Ux>
void reset(_Ux* _Px) // release, take ownership of _Px
shared_ptr(_Px).swap(*this);
template <class _Ux, class _Dx>
void reset(_Ux* _Px, _Dx _Dt) // release, take ownership of _Px, with deleter _Dt
shared_ptr(_Px, _Dt).swap(*this);
template <class _Ux, class _Dx, class _Alloc>
void reset(_Ux* _Px, _Dx _Dt, _Alloc _Ax) // release, take ownership of _Px, with deleter _Dt, allocator _Ax
shared_ptr(_Px, _Dt, _Ax).swap(*this);
template <class _Ty2 = _Ty, enable_if_t<!disjunction_v<is_array<_Ty2>, is_void<_Ty2>>, int> = 0>
_NODISCARD _Ty2& operator*() const noexcept
return *get();
template <class _Ty2 = _Ty, enable_if_t<!is_array_v<_Ty2>, int> = 0>
_NODISCARD _Ty2* operator->() const noexcept
return get();
template <class _Ty2 = _Ty, class _Elem = element_type, enable_if_t<is_array_v<_Ty2>, int> = 0>
_NODISCARD _Elem& operator[](ptrdiff_t _Idx) const noexcept /* strengthened */
return get()[_Idx];
explicit operator bool() const noexcept
return get() != nullptr;
template <class _UxptrOrNullptr, class _Dx>
void _Setpd(const _UxptrOrNullptr _Px, _Dx _Dt) // take ownership of _Px, deleter _Dt
_Temporary_owner_del<_UxptrOrNullptr, _Dx> _Owner(_Px, _Dt);
_Set_ptr_rep_and_enable_shared(
_Owner._Ptr, new _Ref_count_resource<_UxptrOrNullptr, _Dx>(_Owner._Ptr, _STD move(_Dt)));
_Owner._Call_deleter = false;
template <class _UxptrOrNullptr, class _Dx, class _Alloc>
void _Setpda(const _UxptrOrNullptr _Px, _Dx _Dt, _Alloc _Ax) // take ownership of _Px, deleter _Dt, allocator _Ax
using _Alref_alloc = _Rebind_alloc_t<_Alloc, _Ref_count_resource_alloc<_UxptrOrNullptr, _Dx, _Alloc>>;
_Temporary_owner_del<_UxptrOrNullptr, _Dx> _Owner(_Px, _Dt);
_Alref_alloc _Alref(_Ax);
_Alloc_construct_ptr<_Alref_alloc> _Constructor(_Alref);
_Constructor._Allocate();
_Construct_in_place(*_Constructor._Ptr, _Owner._Ptr, _STD move(_Dt), _Ax);
_Set_ptr_rep_and_enable_shared(_Owner._Ptr, _Unfancy(_Constructor._Ptr));
_Constructor._Ptr = nullptr;
_Owner._Call_deleter = false;
template <class _Ux>
void _Set_ptr_rep_and_enable_shared(_Ux* const _Px, _Ref_count_base* const _Rx) noexcept // take ownership of _Px
this->_Ptr = _Px;
this->_Rep = _Rx;
if constexpr (conjunction_v<negation<is_array<_Ty>>, negation<is_volatile<_Ux>>, _Can_enable_shared<_Ux>>)
if (_Px && _Px->_Wptr.expired())
_Px->_Wptr = shared_ptr<remove_cv_t<_Ux>>(*this, const_cast<remove_cv_t<_Ux>*>(_Px));
void _Set_ptr_rep_and_enable_shared(nullptr_t, _Ref_count_base* const _Rx) noexcept // take ownership of nullptr
this->_Ptr = nullptr;
this->_Rep = _Rx;
;
以上是关于c++新特性11 (10)shared_ptr八”shared_ptr类“的主要内容,如果未能解决你的问题,请参考以下文章
c++新特性11 (10)shared_ptr三”创建计数器“
c++新特性11 (10)shared_ptr四”_Ptr_base 类“
c++新特性11 (10)shared_ptr五”构造函数“