shared_ptr 源码分析

  1. 共享指针

    • 说明

      • shared_ptr类提供类的行为接口.

      • 有专门的父类提供数据管理接口.

    • 实现

      • 涉及到继承,以及引用计数是否需要多线程安全.

      • 控制块的类型.

  2. 源码

    • shared_ptr

       template<typename _Tp>
         class shared_ptr : public __shared_ptr<_Tp>
         {
               
               
           template<typename... _Args>
       using _Constructible = typename enable_if<
         is_constructible<__shared_ptr<_Tp>, _Args...>::value
       >::type;
      
           template<typename _Arg>
       using _Assignable = typename enable_if<
         is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
       >::type;
      
         public:
      
           using element_type = typename __shared_ptr<_Tp>::element_type;
      
      #if __cplusplus > 201402L
      # define __cpp_lib_shared_ptr_weak_type 201606
           using weak_type = weak_ptr<_Tp>;
      #endif
           /**
            *  @brief  Construct an empty %shared_ptr.
            *  @post   use_count()==0 && get()==0
            */
           constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() {
               
                }
      
           shared_ptr(const shared_ptr&) noexcept = default;
      
           /**
            *  @brief  Construct a %shared_ptr that owns the pointer @a __p.
            *  @param  __p  A pointer that is convertible to element_type*.
            *  @post   use_count() == 1 && get() == __p
            *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
            */
           template<typename _Yp, typename = _Constructible<_Yp*>>
       explicit
       shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) {
               
                }
      
           /**
            *  @brief  Construct a %shared_ptr that owns the pointer @a __p
            *          and the deleter @a __d.
            *  @param  __p  A pointer.
            *  @param  __d  A deleter.
            *  @post   use_count() == 1 && get() == __p
            *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
            *
            *  Requirements: _Deleter's copy constructor and destructor must
            *  not throw
            *
            *  __shared_ptr will release __p by calling __d(__p)
            */
           template<typename _Yp, typename _Deleter,
              typename = _Constructible<_Yp*, _Deleter>>
       shared_ptr(_Yp* __p, _Deleter __d)
             : __shared_ptr<_Tp>(__p, std::move(__d)) {
               
                }
      
           /**
            *  @brief  Construct a %shared_ptr that owns a null pointer
            *          and the deleter @a __d.
            *  @param  __p  A null pointer constant.
            *  @param  __d  A deleter.
            *  @post   use_count() == 1 && get() == __p
            *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
            *
            *  Requirements: _Deleter's copy constructor and destructor must
            *  not throw
            *
            *  The last owner will call __d(__p)
            */
           template<typename _Deleter>
       shared_ptr(nullptr_t __p, _Deleter __d)
             : __shared_ptr<_Tp>(__p, std::move(__d)) {
               
                }
      
           /**
            *  @brief  Construct a %shared_ptr that owns the pointer @a __p
            *          and the deleter @a __d.
            *  @param  __p  A pointer.
            *  @param  __d  A deleter.
            *  @param  __a  An allocator.
            *  @post   use_count() == 1 && get() == __p
            *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
            *
            *  Requirements: _Deleter's copy constructor and destructor must
            *  not throw _Alloc's copy constructor and destructor must not
            *  throw.
            *
            *  __shared_ptr will release __p by calling __d(__p)
            */
           template<typename _Yp, typename _Deleter, typename _Alloc,
              typename = _Constructible<_Yp*, _Deleter, _Alloc>>
       shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
       : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) {
               
                }
      
           /**
            *  @brief  Construct a %shared_ptr that owns a null pointer
            *          and the deleter @a __d.
            *  @param  __p  A null pointer constant.
            *  @param  __d  A deleter.
            *  @param  __a  An allocator.
            *  @post   use_count() == 1 && get() == __p
            *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
            *
            *  Requirements: _Deleter's copy constructor and destructor must
            *  not throw _Alloc's copy constructor and destructor must not
            *  throw.
            *
            *  The last owner will call __d(__p)
            */
           template<typename _Deleter, typename _Alloc>
       shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
       : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) {
               
                }
      
           // Aliasing constructor
      
           /**
            *  @brief  Constructs a %shared_ptr instance that stores @a __p
            *          and shares ownership with @a __r.
            *  @param  __r  A %shared_ptr.
            *  @param  __p  A pointer that will remain valid while @a *__r is valid.
            *  @post   get() == __p && use_count() == __r.use_count()
            *
            *  This can be used to construct a @c shared_ptr to a sub-object
            *  of an object managed by an existing @c shared_ptr.
            *
            * @code
            * shared_ptr< pair<int,int> > pii(new pair<int,int>());
            * shared_ptr<int> pi(pii, &pii->first);
            * assert(pii.use_count() == 2);
            * @endcode
            */
           template<typename _Yp>
       shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
       : __shared_ptr<_Tp>(__r, __p) {
               
                }
      
           /**
            *  @brief  If @a __r is empty, constructs an empty %shared_ptr;
            *          otherwise construct a %shared_ptr that shares ownership
            *          with @a __r.
            *  @param  __r  A %shared_ptr.
            *  @post   get() == __r.get() && use_count() == __r.use_count()
            */
           template<typename _Yp,
              typename = _Constructible<const shared_ptr<_Yp>&>>
       shared_ptr(const shared_ptr<_Yp>& __r) noexcept
             : __shared_ptr<_Tp>(__r) {
               
                }
      
           /**
            *  @brief  Move-constructs a %shared_ptr instance from @a __r.
            *  @param  __r  A %shared_ptr rvalue.
            *  @post   *this contains the old value of @a __r, @a __r is empty.
            */
           shared_ptr(shared_ptr&& __r) noexcept
           : __shared_ptr<_Tp>(std::move(__r)) {
               
                }
      
           /**
            *  @brief  Move-constructs a %shared_ptr instance from @a __r.
            *  @param  __r  A %shared_ptr rvalue.
            *  @post   *this contains the old value of @a __r, @a __r is empty.
            */
           template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
       shared_ptr(shared_ptr<_Yp>&& __r) noexcept
       : __shared_ptr<_Tp>(std::move(__r)) {
               
                }
      
           /**
            *  @brief  Constructs a %shared_ptr that shares ownership with @a __r
            *          and stores a copy of the pointer stored in @a __r.
            *  @param  __r  A weak_ptr.
            *  @post   use_count() == __r.use_count()
            *  @throw  bad_weak_ptr when __r.expired(),
            *          in which case the constructor has no effect.
            */
           template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
       explicit shared_ptr(const weak_ptr<_Yp>& __r)
       : __shared_ptr<_Tp>(__r) {
               
                }
      
      #if _GLIBCXX_USE_DEPRECATED
      #pragma GCC diagnostic push
      #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
           template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
       shared_ptr(auto_ptr<_Yp>&& __r);
      #pragma GCC diagnostic pop
      #endif
      
           // _GLIBCXX_RESOLVE_LIB_DEFECTS
           // 2399. shared_ptr's constructor from unique_ptr should be constrained
           template<typename _Yp, typename _Del,
              typename = _Constructible<unique_ptr<_Yp, _Del>>>
       shared_ptr(unique_ptr<_Yp, _Del>&& __r)
       : __shared_ptr<_Tp>(std::move(__r)) {
               
                }
      
      #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
           // This non-standard constructor exists to support conversions that
           // were possible in C++11 and C++14 but are ill-formed in C++17.
           // If an exception is thrown this constructor has no effect.
           template<typename _Yp, typename _Del,
         _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
       shared_ptr(unique_ptr<_Yp, _Del>&& __r)
       : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) {
               
                }
      #endif
      
           /**
            *  @brief  Construct an empty %shared_ptr.
            *  @post   use_count() == 0 && get() == nullptr
            */
           constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() {
               
                }
      
           shared_ptr& operator=(const shared_ptr&) noexcept = default;
      
           template<typename _Yp>
       _Assignable<const shared_ptr<_Yp>&>
       operator=(const shared_ptr<_Yp>& __r) noexcept
       {
               
               
         this->__shared_ptr<_Tp>::operator=(__r);
         return *this;
       }
      
      #if _GLIBCXX_USE_DEPRECATED
      #pragma GCC diagnostic push
      #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
           template<typename _Yp>
       _Assignable<auto_ptr<_Yp>>
       operator=(auto_ptr<_Yp>&& __r)
       {
               
               
         this->__shared_ptr<_Tp>::operator=(std::move(__r));
         return *this;
       }
      #pragma GCC diagnostic pop
      #endif
      
           shared_ptr&
           operator=(shared_ptr&& __r) noexcept
           {
               
               
       this->__shared_ptr<_Tp>::operator=(std::move(__r));
       return *this;
           }
      
           template<class _Yp>
       _Assignable<shared_ptr<_Yp>>
       operator=(shared_ptr<_Yp>&& __r) noexcept
       {
               
               
         this->__shared_ptr<_Tp>::operator=(std::move(__r));
         return *this;
       }
      
           template<typename _Yp, typename _Del>
       _Assignable<unique_ptr<_Yp, _Del>>
       operator=(unique_ptr<_Yp, _Del>&& __r)
       {
               
               
         this->__shared_ptr<_Tp>::operator=(std::move(__r));
         return *this;
       }
      
         private:
           // This constructor is non-standard, it is used by allocate_shared.
           template<typename _Alloc, typename... _Args>
       shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
            _Args&&... __args)
       : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
       {
               
                }
      
           template<typename _Yp, typename _Alloc, typename... _Args>
       friend shared_ptr<_Yp>
       allocate_shared(const _Alloc& __a, _Args&&... __args);
      
           // This constructor is non-standard, it is used by weak_ptr::lock().
           shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
           : __shared_ptr<_Tp>(__r, std::nothrow) {
               
                }
      
           friend class weak_ptr<_Tp>;
         };
      
      
      • 可以看到父类__shared_ptr,shared_ptr没有提供任何成员变量.

    • 说明

      • 提供的都是一些数据操作函数.

  3. 数据类

    • 源码

       template<typename _Tp, _Lock_policy _Lp>
         class __shared_ptr
         : public __shared_ptr_access<_Tp, _Lp>
         {
               
               
         public:
           using element_type = typename remove_extent<_Tp>::type;
      
         private:
           // Constraint for taking ownership of a pointer of type _Yp*:
           template<typename _Yp>
       using _SafeConv
         = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
      
           // Constraint for construction from shared_ptr and weak_ptr:
           template<typename _Yp, typename _Res = void>
       using _Compatible = typename
         enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
      
           // Constraint for assignment from shared_ptr and weak_ptr:
           template<typename _Yp>
       using _Assignable = _Compatible<_Yp, __shared_ptr&>;
      
           // Constraint for construction from unique_ptr:
           template<typename _Yp, typename _Del, typename _Res = void,
              typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
       using _UniqCompatible = typename enable_if<__and_<
         __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*>
         >::value, _Res>::type;
      
           // Constraint for assignment from unique_ptr:
           template<typename _Yp, typename _Del>
       using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
      
         public:
      
      #if __cplusplus > 201402L
           using weak_type = __weak_ptr<_Tp, _Lp>;
      #endif
      
           constexpr __shared_ptr() noexcept
           : _M_ptr(0), _M_refcount()
           {
               
                }
      
           template<typename _Yp, typename = _SafeConv<_Yp>>
       explicit
       __shared_ptr(_Yp* __p)
       : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
       {
               
               
         static_assert( !is_void<_Yp>::value, "incomplete type" );
         static_assert( sizeof(_Yp) > 0, "incomplete type" );
         _M_enable_shared_from_this_with(__p);
       }
      
           template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
       __shared_ptr(_Yp* __p, _Deleter __d)
       : _M_ptr(__p), _M_refcount(__p, std::move(__d))
       {
               
               
         static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
             "deleter expression d(p) is well-formed");
         _M_enable_shared_from_this_with(__p);
       }
      
           template<typename _Yp, typename _Deleter, typename _Alloc,
              typename = _SafeConv<_Y
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值