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七reset

c++新特性11 (10)shared_ptr四”_Ptr_base 类“

c++新特性11 (10)shared_ptr五”构造函数“

c++新特性11 (10)shared_ptr二”_Ref_count_base类“

c++新特性11 (10)shared_ptr六”构造函数unique_ptr参数“