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:
      /// The type pointed to by the stored pointer, remove_extent_t<_Tp>
      using element_type = typename __shared_ptr<_Tp>::element_type;

#if __cplusplus >= 201703L
#define __cpp_lib_shared_ptr_weak_type 201606L
      /// The corresponding weak_ptr type for this shared_ptr
      /// @since C++17
      using weak_type = weak_ptr<_Tp>;
#endif

      constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }

      shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor

      template<typename _Yp, typename = _Constructible<_Yp*>>
	  explicit shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }

      template<typename _Yp, typename _Deleter,
	       typename = _Constructible<_Yp*, _Deleter>>
	  shared_ptr(_Yp* __p, _Deleter __d)
        : __shared_ptr<_Tp>(__p, std::move(__d)) { }

      template<typename _Deleter>
	shared_ptr(nullptr_t __p, _Deleter __d)
        : __shared_ptr<_Tp>(__p, std::move(__d)) { }

      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)) { }

      template<typename _Deleter, typename _Alloc>
	shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }

      template<typename _Yp>
	shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
	: __shared_ptr<_Tp>(__r, __p) { }

#if __cplusplus > 201703L
      template<typename _Yp>
	shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
	: __shared_ptr<_Tp>(std::move(__r), __p) { }
#endif

      template<typename _Yp,
	       typename = _Constructible<const shared_ptr<_Yp>&>>
	shared_ptr(const shared_ptr<_Yp>& __r) noexcept
        : __shared_ptr<_Tp>(__r) { }

      shared_ptr(shared_ptr&& __r) noexcept
      : __shared_ptr<_Tp>(std::move(__r)) { }

      template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
	shared_ptr(shared_ptr<_Yp>&& __r) noexcept
	: __shared_ptr<_Tp>(std::move(__r)) { }

      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_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
	: __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
	{ }

      template<typename _Yp, typename _Alloc, typename... _Args>
	friend shared_ptr<_NonArray<_Yp>>
	allocate_shared(const _Alloc&, _Args&&...);

      template<typename _Yp, typename... _Args>
	friend shared_ptr<_NonArray<_Yp>>
	make_shared(_Args&&...);

#if __cpp_lib_shared_ptr_arrays >= 201707L
      // This constructor is non-standard, it is used by allocate_shared<T[]>.
      template<typename _Alloc, typename _Init = const remove_extent_t<_Tp>*>
	shared_ptr(const _Sp_counted_array_base<_Alloc>& __a,
		   _Init __init = nullptr)
	: __shared_ptr<_Tp>(__a, __init)
	{ }

      template<typename _Yp, typename _Alloc>
	friend shared_ptr<_UnboundedArray<_Yp>>
	allocate_shared(const _Alloc&, size_t);

      template<typename _Yp>
	friend shared_ptr<_UnboundedArray<_Yp>>
	make_shared(size_t);

      template<typename _Yp, typename _Alloc>
	friend shared_ptr<_UnboundedArray<_Yp>>
	allocate_shared(const _Alloc&, size_t, const remove_extent_t<_Yp>&);

      template<typename _Yp>
	friend shared_ptr<_UnboundedArray<_Yp>>
	make_shared(size_t, const remove_extent_t<_Yp>&);

      template<typename _Yp, typename _Alloc>
	friend shared_ptr<_BoundedArray<_Yp>>
	allocate_shared(const _Alloc&);

      template<typename _Yp>
	friend shared_ptr<_BoundedArray<_Yp>>
	make_shared();

      template<typename _Yp, typename _Alloc>
	friend shared_ptr<_BoundedArray<_Yp>>
	allocate_shared(const _Alloc&, const remove_extent_t<_Yp>&);

      template<typename _Yp>
	friend shared_ptr<_BoundedArray<_Yp>>
	make_shared(const remove_extent_t<_Yp>&);

#if __cpp_lib_smart_ptr_for_overwrite
      template<typename _Yp, typename _Alloc>
	friend shared_ptr<_NotUnboundedArray<_Yp>>
	allocate_shared_for_overwrite(const _Alloc&);

      template<typename _Yp>
	friend shared_ptr<_NotUnboundedArray<_Yp>>
	make_shared_for_overwrite();

      template<typename _Yp, typename _Alloc>
	friend shared_ptr<_UnboundedArray<_Yp>>
	allocate_shared_for_overwrite(const _Alloc&, size_t);

      template<typename _Yp>
	friend shared_ptr<_UnboundedArray<_Yp>>
	make_shared_for_overwrite(size_t);
#endif
#endif

      // This constructor is non-standard, it is used by weak_ptr::lock().
      shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept
      : __shared_ptr<_Tp>(__r, std::nothrow) { }

      friend class weak_ptr<_Tp>;
    }

从上面class shared_ptr的定义来看只是继承了class __shared_ptr,并没有涉及ref count相关的实现。下面来看看其父类class __shared_ptr的定义:

template<typename _Tp, _Lock_policy _Lp>
class __shared_ptr
{
    public:
      typedef _Tp   element_type;
      
      __shared_ptr()
      : _M_ptr(0), _M_refcount() // never throws
      { }

      template<typename _Tp1>
        explicit
        __shared_ptr(_Tp1* __p)
	: _M_ptr(__p), _M_refcount(__p)
        {
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
	  typedef int _IsComplete[sizeof(_Tp1)];
	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
	}

      template<typename _Tp1, typename _Deleter>
        __shared_ptr(_Tp1* __p, _Deleter __d)
        : _M_ptr(__p), _M_refcount(__p, __d)
        {
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
	}
      
      //  generated copy constructor, assignment, destructor are fine.
      
      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }

      template<typename _Tp1>
        explicit
        __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
	: _M_refcount(__r._M_refcount) // may throw
        {
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
	  // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
	  // did not throw.
	  _M_ptr = __r._M_ptr;
	}

#if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      // Postcondition: use_count() == 1 and __r.get() == 0
      template<typename _Tp1>
        explicit
        __shared_ptr(std::auto_ptr<_Tp1>& __r)
	: _M_ptr(__r.get()), _M_refcount()
        { // TODO requries delete __r.release() well-formed
	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
	  typedef int _IsComplete[sizeof(_Tp1)];
	  _Tp1* __tmp = __r.get();
	  _M_refcount = __shared_count<_Lp>(__r);
	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
	}
#pragma GCC diagnostic pop
#endif

      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
	: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
	  _M_refcount(__r._M_refcount)
        { }

      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
	: _M_ptr(const_cast<element_type*>(__r._M_ptr)),
	  _M_refcount(__r._M_refcount)
        { }

      template<typename _Tp1>
        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
	: _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
	  _M_refcount(__r._M_refcount)
        {
	  if (_M_ptr == 0) // need to allocate new counter -- the cast failed
	    _M_refcount = __shared_count<_Lp>();
	}

      template<typename _Tp1>
        __shared_ptr&
        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
        {
	  _M_ptr = __r._M_ptr;
	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
	  return *this;
	}

#if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      template<typename _Tp1>
        __shared_ptr&
        operator=(std::auto_ptr<_Tp1>& __r)
        {
	  __shared_ptr(__r).swap(*this);
	  return *this;
	}
#pragma GCC diagnostic pop
#endif

      void
      reset() // never throws
      { __shared_ptr().swap(*this); }

      template<typename _Tp1>
        void
        reset(_Tp1* __p) // _Tp1 must be complete.
        {
	  // Catch self-reset errors.
	  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 
	  __shared_ptr(__p).swap(*this);
	}

      template<typename _Tp1, typename _Deleter>
        void
        reset(_Tp1* __p, _Deleter __d)
        { __shared_ptr(__p, __d).swap(*this); }

      // Allow class instantiation when _Tp is [cv-qual] void.
      typename std::tr1::add_reference<_Tp>::type
      operator*() const // never throws
      {
	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
	return *_M_ptr;
      }

      _Tp*
      operator->() const // never throws
      {
	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
	return _M_ptr;
      }
    
      _Tp*
      get() const // never throws
      { return _M_ptr; }

      // Implicit conversion to "bool"
    private:
      typedef _Tp* __shared_ptr::*__unspecified_bool_type;

    public:
      operator __unspecified_bool_type() const // never throws
      { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }

      bool
      unique() const // never throws
      { return _M_refcount._M_unique(); }

      long
      use_count() const // never throws
      { return _M_refcount._M_get_use_count(); }

      void
      swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
      {
	std::swap(_M_ptr, __other._M_ptr);
	_M_refcount._M_swap(__other._M_refcount);
      }

    private:
      void*
      _M_get_deleter(const std::type_info& __ti) const
      { return _M_refcount._M_get_deleter(__ti); }

      template<typename _Tp1, _Lock_policy _Lp1>
        bool
        _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
        { return _M_refcount < __rhs._M_refcount; }

      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;

      template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
        friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);

      // Friends injected into enclosing namespace and found by ADL:
      template<typename _Tp1>
        friend inline bool
        operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
        { return __a.get() == __b.get(); }

      template<typename _Tp1>
        friend inline bool
        operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
        { return __a.get() != __b.get(); }

      template<typename _Tp1>
        friend inline bool
        operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
        { return __a._M_less(__b); }

      _Tp*         	   _M_ptr;         // Contained pointer.
      __shared_count<_Lp>  _M_refcount;    // Reference counter.
    }

从__shared_ptr的定义来看,其中有两个重要的成员:

      _Tp*                _M_ptr;         // Contained pointer.
      __shared_count<_Lp>  _M_refcount;    // Reference counter.

template<_Lock_policy _Lp = __default_lock_policy>
class __shared_count
{
    public: 
      __shared_count()
      : _M_pi(0) // nothrow
      { }
  
      template<typename _Ptr>
        __shared_count(_Ptr __p) : _M_pi(0)
        {
	  __try
	    {
	      typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
	          __p, _Sp_deleter<_Tp>());
	    }
	  __catch(...)
	    {
	      delete __p;
	      __throw_exception_again;
	    }
	}

      template<typename _Ptr, typename _Deleter>
        __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
        {
	  __try
	    {
	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
	    }
	  __catch(...)
	    {
	      __d(__p); // Call _Deleter on __p.
	      __throw_exception_again;
	    }
	}

#if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      // Special case for auto_ptr<_Tp> to provide the strong guarantee.
      template<typename _Tp>
        explicit
        __shared_count(std::auto_ptr<_Tp>& __r)
	: _M_pi(new _Sp_counted_base_impl<_Tp*,
		_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
        { __r.release(); }
#pragma GCC diagnostic pop
#endif

      // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
      explicit
      __shared_count(const __weak_count<_Lp>& __r);
  
      ~__shared_count() // nothrow
      {
	if (_M_pi != 0)
	  _M_pi->_M_release();
      }
      
      __shared_count(const __shared_count& __r)
      : _M_pi(__r._M_pi) // nothrow
      {
	if (_M_pi != 0)
	  _M_pi->_M_add_ref_copy();
      }
  
      __shared_count&
      operator=(const __shared_count& __r) // nothrow
      {
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
	if (__tmp != _M_pi)
	  {
	    if (__tmp != 0)
	      __tmp->_M_add_ref_copy();
	    if (_M_pi != 0)
	      _M_pi->_M_release();
	    _M_pi = __tmp;
	  }
	return *this;
      }
  
      void
      _M_swap(__shared_count& __r) // nothrow
      {
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
	__r._M_pi = _M_pi;
	_M_pi = __tmp;
      }
  
      long
      _M_get_use_count() const // nothrow
      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }

      bool
      _M_unique() const // nothrow
      { return this->_M_get_use_count() == 1; }
      
      friend inline bool
      operator==(const __shared_count& __a, const __shared_count& __b)
      { return __a._M_pi == __b._M_pi; }
  
      friend inline bool
      operator<(const __shared_count& __a, const __shared_count& __b)
      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
  
      void*
      _M_get_deleter(const std::type_info& __ti) const
      { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }

    private:
      friend class __weak_count<_Lp>;

      _Sp_counted_base<_Lp>*  _M_pi;
    }

class __shared_count 中的重要成员:_Sp_counted_base<_Lp>*  _M_pi;

template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
class _Sp_counted_base_impl
    : public _Sp_counted_base<_Lp>
{
    public:
      // Precondition: __d(__p) must not throw.
      _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
      : _M_ptr(__p), _M_del(__d) { }
    
      virtual void
      _M_dispose() // nothrow
      { _M_del(_M_ptr); }
      
      virtual void*
      _M_get_deleter(const std::type_info& __ti)
      {
#if __cpp_rtti
        return __ti == typeid(_Deleter) ? &_M_del : 0;
#else
        return 0;
#endif
      }
      
    private:
      _Sp_counted_base_impl(const _Sp_counted_base_impl&);
      _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
      
      _Ptr      _M_ptr;  // copy constructor must not throw
      _Deleter  _M_del;  // copy constructor must not throw
};

从上面的定义来看,_Sp_counted_base_impl中并没有实现ref count的加,减。因此我们看看其父类_Sp_counted_base的定义:

  template<_Lock_policy _Lp = __default_lock_policy>
    class _Sp_counted_base
    : public _Mutex_base<_Lp>
{
    public:  
      _Sp_counted_base()
      : _M_use_count(1), _M_weak_count(1) { }
      
      virtual
      ~_Sp_counted_base() // nothrow 
      { }
  
      // Called when _M_use_count drops to zero, to release the resources
      // managed by *this.
      virtual void
      _M_dispose() = 0; // nothrow
      
      // Called when _M_weak_count drops to zero.
      virtual void
      _M_destroy() // nothrow
      { delete this; }
      
      virtual void*
      _M_get_deleter(const std::type_info&) = 0;

      void
      _M_add_ref_copy()
      { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
  
      void
      _M_add_ref_lock();
      
      void
      _M_release() // nothrow
      {
        // Be race-detector-friendly.  For more info see bits/c++config.
        _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
	  {
            _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
	    _M_dispose();
	    // There must be a memory barrier between dispose() and destroy()
	    // to ensure that the effects of dispose() are observed in the
	    // thread that runs destroy().
	    // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
	    if (_Mutex_base<_Lp>::_S_need_barriers)
	      {
		__atomic_thread_fence (__ATOMIC_ACQ_REL);
	      }

            // Be race-detector-friendly.  For more info see bits/c++config.
            _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
						       -1) == 1)
              {
                _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
	        _M_destroy();
              }
	  }
      }
  
      void
      _M_weak_add_ref() // nothrow
      { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }

      void
      _M_weak_release() // nothrow
      {
        // Be race-detector-friendly. For more info see bits/c++config.
        _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
	  {
            _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
	    if (_Mutex_base<_Lp>::_S_need_barriers)
	      {
	        // See _M_release(),
	        // destroy() must observe results of dispose()
		__atomic_thread_fence (__ATOMIC_ACQ_REL);
	      }
	    _M_destroy();
	  }
      }
  
      long
      _M_get_use_count() const // nothrow
      {
        // No memory barrier is used here so there is no synchronization
        // with other threads.
        return const_cast<const volatile _Atomic_word&>(_M_use_count);
      }

    private:  
      _Sp_counted_base(_Sp_counted_base const&);
      _Sp_counted_base& operator=(_Sp_counted_base const&);

      _Atomic_word  _M_use_count;     // #shared
      _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
    }

类关系图 

 总结一下,shared_ptr的类关系图如上图所示,在_Sp_counted_base中成员_M_use_count是表示引用计数的值。其中加一有两个函数:

    _Sp_counted_base<xxxx>::_M_add_ref_lock();

    _Sp_counted_base<xxxx>::_M_add_ref_copy();

减一有函数:

  _Sp_counted_base<xxxx>::_M_release();

下面我们来看看引用计数什么时候加一,什么时候减一。

引用计数加一

shared_ptr这个类构造,赋值,拷贝构造的时候

//构造时,赋值为1
 _Sp_counted_base()
      : _M_use_count(1), _M_weak_count(1) { }

//拷贝构造
__shared_count(const __shared_count& __r) noexcept: _M_pi(__r._M_pi)
{
	if (_M_pi != nullptr)
	  _M_pi->_M_add_ref_copy();
}

//赋值
__shared_count&
operator=(const __shared_count& __r) noexcept
{
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
	if (__tmp != _M_pi)
	  {
	    if (__tmp != nullptr)
	      __tmp->_M_add_ref_copy();
	    if (_M_pi != nullptr)
	      _M_pi->_M_release();
	    _M_pi = __tmp;
	  }
	return *this;
}

引用计数减一

shared_ptr这个类析构,赋值的时候。

//赋值
__shared_count&
operator=(const __shared_count& __r) noexcept
{
	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
	if (__tmp != _M_pi)
	  {
	    if (__tmp != nullptr)
	      __tmp->_M_add_ref_copy();
	    if (_M_pi != nullptr)
	      _M_pi->_M_release();
	    _M_pi = __tmp;
	  }
	return *this;
}

//析构
~__shared_count() noexcept
{
	if (_M_pi != nullptr)
	  _M_pi->_M_release();
}

 代码示例

示例1

#include<iostream>
#include <memory>
using namespace std;

class node
{
public:
        node(int a) { age_ = a;}
        ~node() { cout << "destruct, age_:" << age_ << endl; }
private:
        int age_ = 0;
};

int main() {
        shared_ptr<node> p = make_shared<node>(1);
        shared_ptr<node> q = make_shared<node>(2);
        cout << "count for p:" << p.use_count() << endl;
        cout << "count for q:" << q.use_count() << endl;
        //拷贝构造函数,引用计数+1,被托管的指针分别被p 和 rp引用,所以引用计数是2
        shared_ptr<node> rp(p);
        cout << "count for rp:" << rp.use_count()
             << ", count for p:" << p.use_count() << endl;
        //操作符 =, 引用计数+1, 被托管的指针分别被q 和 rq引用,所以引用计数是2
        shared_ptr<node> rq = q;
        cout << "count for rq:" << rq.use_count()
             << ", count for q:" << p.use_count()  << endl;
        return 0;
}

运行结果:

 示例2

#include<iostream>
#include <memory>
using namespace std;

class node
{
public:
        node(int a) { age_ = a;}
        ~node() { cout << "destruct, age_:" << age_ << endl; }
private:
        int age_ = 0;
};

int main() {
        shared_ptr<node> p = make_shared<node>(1);
        shared_ptr<node> q = make_shared<node>(2);
        cout << "count for p:" << p.use_count() << endl;
        cout << "count for q:" << q.use_count() << endl;
        //p原来托管的指针引用计数减一,q 托管的指针引用计数加一
        //所以age = 1 的node指针对象因引用计数为0,被析构
        p = q;
        cout << "count for p:" << p.use_count()
             << ", count for q:" << p.use_count() << endl;
        return 0;
}

运行结果:

 示例3

#include<iostream>
#include <memory>
using namespace std;

class node
{
public:
        node(int a) { age_ = a;}
        ~node() { cout << "destruct, age_:" << age_ << endl; }
private:
        int age_ = 0;
};

int main() {
        node* t = new node(3);
        //将同一个原始指针给不同的shared_ptr对象,程序会异常,挂掉
        shared_ptr<node> r(t);
        shared_ptr<node> p(t);
        cout << "count for p:" << p.use_count() << endl;
        cout << "count for r:" << r.use_count() << endl;

        return 0;
}

运行结果:

 示例4

#include<iostream>
#include <memory>
using namespace std;

class node
{
public:
        node(int a) { age_ = a;}
        ~node() { cout << "destruct, age_:" << age_ << endl; }
private:
        int age_ = 0;
};

int main() {
        shared_ptr<node> r = make_shared<node>(1);
        //运行shared_ptr的移动构造函数, r变成一个空shared_ptr
        shared_ptr<node> p(move(r));
        cout << "count for p:" << p.use_count() << endl;
        cout << "count for r:" << r.use_count() << endl;

        return 0;
}

运行结果:

 更多细节: C++11 shared_ptr智能指针(超级详细)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值