定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 template <class T >class shared_ptr { public : typedef T element_type; typedef weak_ptr<T> weak_type; constexpr shared_ptr () noexcept ; template <class Y> explicit shared_ptr (Y* p) ; template <class Y, class D> shared_ptr (Y* p, D d) ; template <class Y, class D, class A> shared_ptr (Y* p, D d, A a) ; template <class D > shared_ptr (nullptr_t p, D d); template <class D , class A > shared_ptr (nullptr_t p, D d, A a); template <class Y> shared_ptr (const shared_ptr<Y>& r, T *p) noexcept ; shared_ptr (const shared_ptr& r) noexcept ; template <class Y> shared_ptr (const shared_ptr<Y>& r) noexcept ; shared_ptr (shared_ptr&& r) noexcept ; template <class Y> shared_ptr (shared_ptr<Y>&& r) noexcept ; template <class Y> explicit shared_ptr (const weak_ptr<Y>& r) ; template <class Y> shared_ptr (auto_ptr<Y>&& r) ; template <class Y , class D > shared_ptr (unique_ptr<Y, D>&& r); shared_ptr (nullptr_t ) : shared_ptr () { } ~shared_ptr (); shared_ptr& operator =(const shared_ptr& r) noexcept ; template <class Y > shared_ptr& operator =(const shared_ptr<Y>& r) noexcept ; shared_ptr& operator =(shared_ptr&& r) noexcept ; template <class Y > shared_ptr& operator =(shared_ptr<Y>&& r); template <class Y > shared_ptr& operator =(auto_ptr<Y>&& r); template <class Y , class D > shared_ptr& operator =(unique_ptr<Y, D>&& r); void swap (shared_ptr& r) noexcept ; void reset () noexcept ; template <class Y> void reset (Y* p) ; template <class Y, class D> void reset (Y* p, D d) ; template <class Y, class D, class A> void reset (Y* p, D d, A a) ; T* get () const noexcept ; T& operator *() const noexcept ; T* operator ->() const noexcept ; long use_count () const noexcept ; bool unique () const noexcept ; explicit operator bool () const noexcept ; template <class U> bool owner_before (shared_ptr<U> const & b) const noexcept ; template <class U> bool owner_before (weak_ptr<U> const & b) const noexcept ; };
实现 引用计数块 shared_ptr与unique_ptr的区别在于,shared_ptr内部会创建一个引用计数块,多个shared_ptr对象可以共享同一个引用计数块,来达到对同一个指针的状态进行共享的目的。
__shared_count shared_count定义了引用计数块的基本接口,__shared_owners_用来记录引用数,__add_shared函数用来对引用计数+1,__release_shared用来对引用计数-1,每一次操作都是原子操作。当引用计数归0的时候,会调用__on_zero_shared来进行销毁操作。use_count用来查询当前的引用计数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class __shared_count { __shared_count(const __shared_count&); __shared_count& operator =(const __shared_count&); protected : long __shared_owners_; virtual ~__shared_count(); private : virtual void __on_zero_shared() _NOEXCEPT = 0 ; public : explicit __shared_count(long __refs = 0 ) _NOEXCEPT : __shared_owners_(__refs) {} #if defined(_LIBCPP_BUILDING_LIBRARY) && \ defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) void __add_shared() _NOEXCEPT; bool __release_shared() _NOEXCEPT; #else void __add_shared() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_owners_); } bool __release_shared() _NOEXCEPT { if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1 ) { __on_zero_shared(); return true ; } return false ; } #endif long use_count () const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1 ; } };
__shared_weak_count __shared_weak_count是__shared_count的派生类,在其基础上,定义了弱引用计数的接口。__shared_weak_owners_用来记录弱引用数,__add_weak函数用来对弱引用计数+1,__release_weak用来对弱引用计数-1,每一次操作都是原子操作。当弱引用计数归0或者强引用计数归0的时候,会调用__on_zero_shared_weak。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 class __shared_weak_count : private __shared_count { long __shared_weak_owners_; public : explicit __shared_weak_count(long __refs = 0 ) _NOEXCEPT : __shared_count(__refs), __shared_weak_owners_(__refs) {} protected : virtual ~__shared_weak_count(); public :#if defined(_LIBCPP_BUILDING_LIBRARY) && \ defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) void __add_shared() _NOEXCEPT; void __add_weak() _NOEXCEPT; void __release_shared() _NOEXCEPT; #else void __add_shared() _NOEXCEPT { __shared_count::__add_shared(); } void __add_weak() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_weak_owners_); } void __release_shared() _NOEXCEPT { if (__shared_count::__release_shared()) __release_weak(); } #endif void __release_weak() _NOEXCEPT; long use_count () const _NOEXCEPT {return __shared_count::use_count ();} __shared_weak_count* lock () _NOEXCEPT ; virtual const void * __get_deleter(const type_info&) const _NOEXCEPT; private : virtual void __on_zero_shared_weak() _NOEXCEPT = 0 ; }; void __shared_weak_count::__release_weak() noexcept { if (__libcpp_atomic_load(&__shared_weak_owners_, _AO_Acquire) == 0 ) { __on_zero_shared_weak(); } else if (__libcpp_atomic_refcount_decrement(__shared_weak_owners_) == -1 ) __on_zero_shared_weak(); } __shared_weak_count* __shared_weak_count::lock () noexcept { long object_owners = __libcpp_atomic_load(&__shared_owners_); while (object_owners != -1 ) { if (__libcpp_atomic_compare_exchange(&__shared_owners_, &object_owners, object_owners+1 )) return this ; } return nullptr ; }
__shared_ptr_pointer __shared_ptr_pointer是引用计数块的实现类,派生自__shared_weak_count。模板参数_Tp为维护的对象类型,_Dp为删除器,_Alloc为分配器,__data_用来存储了这三个参数值。负责实现__on_zero_shared和__on_zero_shared_weak。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 template <class _Tp , class _Dp , class _Alloc >class __shared_ptr_pointer : public __shared_weak_count { __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_; public : _LIBCPP_INLINE_VISIBILITY __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a) : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move (__d)), _VSTD::move (__a)) {} #ifndef _LIBCPP_NO_RTTI virtual const void * __get_deleter(const type_info&) const _NOEXCEPT; #endif private : virtual void __on_zero_shared() _NOEXCEPT; virtual void __on_zero_shared_weak() _NOEXCEPT; }; template <class _Tp , class _Dp , class _Alloc >void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT{ __data_.first ().second ()(__data_.first ().first ()); __data_.first ().second ().~_Dp(); } template <class _Tp , class _Dp , class _Alloc >void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT{ typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al; typedef allocator_traits<_Al> _ATraits; typedef pointer_traits<typename _ATraits::pointer> _PTraits; _Al __a(__data_.second ()); __data_.second ().~_Alloc(); __a.deallocate (_PTraits::pointer_to (*this ), 1 ); }
内部类型定义 weak_type
1 2 3 4 #if _LIBCPP_STD_VER > 14 typedef weak_ptr<_Tp> weak_type; #else #endif
element_type 表示维护对象的类型,remove_extent_t用于获取数组内元素的类型
1 2 3 4 5 #if _LIBCPP_STD_VER > 14 typedef remove_extent_t <_Tp> element_type; #else typedef _Tp element_type; #endif
属性 _ptr __ptr_就是维护的指针
_cntrl __cntrl_是引用计数块的指针,是shared_ptr_pointer类型
1 __shared_weak_count* __cntrl_;
构造函数 shared_ptr(_Yp __p) *
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 template <class _Yp , class = _EnableIf< _And< __compatible_with<_Yp, _Tp> #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC) , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> > #endif >::value > > explicit shared_ptr (_Yp* __p) : __ptr_(__p) { unique_ptr<_Yp> __hold(__p); typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk; __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT()); __hold.release (); __enable_weak_this(__p, __p); }
shared_ptr(const shared_ptr& __r)
1 2 3 4 5 6 7 8 9 template <class _Tp >inline shared_ptr<_Tp>::shared_ptr (const shared_ptr& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { if (__cntrl_) __cntrl_->__add_shared(); }
shared_ptr(shared_ptr&& __r)
1 2 3 4 5 6 7 8 9 template <class _Tp >inline shared_ptr<_Tp>::shared_ptr (shared_ptr&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { __r.__ptr_ = nullptr ; __r.__cntrl_ = nullptr ; }
shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 template <class _Tp >template <class _Yp , class _Dp >shared_ptr<_Tp>::shared_ptr (unique_ptr<_Yp, _Dp>&& __r, typename enable_if < !is_lvalue_reference<_Dp>::value && is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, __nat >::type) : __ptr_(__r.get ()) { #if _LIBCPP_STD_VER > 11 if (__ptr_ == nullptr ) __cntrl_ = nullptr ; else #endif { typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get (), __r.get_deleter (), _AllocT()); __enable_weak_this(__r.get (), __r.get ()); } __r.release (); }
shared_ptr(const weak_ptr<_Yp>& __r)
1 2 3 4 5 6 7 8 9 10 template <class _Tp >template <class _Yp >shared_ptr<_Tp>::shared_ptr (const weak_ptr<_Yp>& __r, typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock () : __r.__cntrl_) { if (__cntrl_ == nullptr ) __throw_bad_weak_ptr(); }
析构函数 1 2 3 4 5 6 template <class _Tp >shared_ptr<_Tp>::~shared_ptr () { if (__cntrl_) __cntrl_->__release_shared(); }
赋值函数 operator=(const shared_ptr& __r)
1 2 3 4 5 6 7 8 template <class _Tp >inline shared_ptr<_Tp>& shared_ptr<_Tp>::operator =(const shared_ptr& __r) _NOEXCEPT { shared_ptr (__r).swap (*this ); return *this ; }
operator=(shared_ptr&& __r)
1 2 3 4 5 6 7 8 template <class _Tp >inline shared_ptr<_Tp>& shared_ptr<_Tp>::operator =(shared_ptr&& __r) _NOEXCEPT { shared_ptr (_VSTD::move (__r)).swap (*this ); return *this ; }
operator=(unique_ptr<_Yp, _Dp>&& __r)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 template <class _Tp >template <class _Yp , class _Dp >inline typename enable_if< is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, typename shared_ptr<_Tp>::element_type*>::value, shared_ptr<_Tp>& >::type shared_ptr<_Tp>::operator =(unique_ptr<_Yp, _Dp>&& __r) { shared_ptr (_VSTD::move (__r)).swap (*this ); return *this ; }
操作函数 swap(shared_ptr& __r)
1 2 3 4 5 6 7 8 template <class _Tp >inline void shared_ptr<_Tp>::swap (shared_ptr& __r) _NOEXCEPT { _VSTD::swap (__ptr_, __r.__ptr_); _VSTD::swap (__cntrl_, __r.__cntrl_); }
reset()
1 2 3 4 5 6 7 template <class _Tp >inline void shared_ptr<_Tp>::reset () _NOEXCEPT { shared_ptr ().swap (*this ); }
reset(_Yp __p) *
1 2 3 4 5 6 7 8 9 10 11 12 template <class _Tp >template <class _Yp >inline typename enable_if< __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, void >::type shared_ptr<_Tp>::reset (_Yp* __p) { shared_ptr (__p).swap (*this ); }
工厂函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 template <class _Tp , class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared (_Args&& ...__args) { return _VSTD::allocate_shared <_Tp>(allocator <_Tp>(), _VSTD::forward<_Args>(__args)...); } template <class _Tp , class _Alloc , class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared (const _Alloc& __a, _Args&& ...__args) { using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>; using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type; __allocation_guard<_ControlBlockAllocator> __guard(__a, 1 ); ::new ((void *)_VSTD::addressof (*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...); auto __control_block = __guard.__release_ptr(); return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof (*__control_block)); }
类型转换 对shared_ptr内的指针进行类型转换
1 2 3 4 5 6 7 8 9 template <class _Tp, class _Up>inline _LIBCPP_INLINE_VISIBILITYshared_ptr<_Tp> static_pointer_cast (const shared_ptr<_Up>& __r) _NOEXCEPT { return shared_ptr <_Tp>(__r, static_cast < typename shared_ptr<_Tp>::element_type*>(__r.get ())); }
1 2 3 4 5 6 7 8 9 template <class _Tp, class _Up>inline _LIBCPP_INLINE_VISIBILITYshared_ptr<_Tp> dynamic_pointer_cast (const shared_ptr<_Up>& __r) _NOEXCEPT { typedef typename shared_ptr<_Tp>::element_type _ET; _ET* __p = dynamic_cast <_ET*>(__r.get ()); return __p ? shared_ptr <_Tp>(__r, __p) : shared_ptr <_Tp>(); }
1 2 3 4 5 6 7 template <class _Tp, class _Up>shared_ptr<_Tp> const_pointer_cast (const shared_ptr<_Up>& __r) _NOEXCEPT { typedef typename shared_ptr<_Tp>::element_type _RTp; return shared_ptr <_Tp>(__r, const_cast <_RTp*>(__r.get ())); }
1 2 3 4 5 6 7 8 template <class _Tp, class _Up>shared_ptr<_Tp> reinterpret_pointer_cast (const shared_ptr<_Up>& __r) _NOEXCEPT { return shared_ptr <_Tp>(__r, reinterpret_cast < typename shared_ptr<_Tp>::element_type*>(__r.get ())); }
enable_shared_from_this 提供enable_shared_from_this接口,用于通过Tp指针获取到已经创建过的shared_ptr对象,用于共享同一个shared_ptr。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 template <class _Tp >class _LIBCPP_TEMPLATE_VIS enable_shared_from_this{ mutable weak_ptr<_Tp> __weak_this_; protected : _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR enable_shared_from_this () _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY enable_shared_from_this (enable_shared_from_this const &) _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY enable_shared_from_this& operator =(enable_shared_from_this const &) _NOEXCEPT {return *this ;} _LIBCPP_INLINE_VISIBILITY ~enable_shared_from_this () {} public : _LIBCPP_INLINE_VISIBILITY shared_ptr<_Tp> shared_from_this () {return shared_ptr <_Tp>(__weak_this_);} _LIBCPP_INLINE_VISIBILITY shared_ptr<_Tp const > shared_from_this () const {return shared_ptr <const _Tp>(__weak_this_);}#if _LIBCPP_STD_VER > 14 _LIBCPP_INLINE_VISIBILITY weak_ptr<_Tp> weak_from_this () _NOEXCEPT { return __weak_this_; } _LIBCPP_INLINE_VISIBILITY weak_ptr<const _Tp> weak_from_this () const _NOEXCEPT { return __weak_this_; }#endif template <class _Up > friend class shared_ptr ; };