libc++源码分析之std::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
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; // C++17

// constructors:
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); // removed in C++17
template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
shared_ptr(nullptr_t) : shared_ptr() { }

// destructor:
~shared_ptr();

// assignment:
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); // removed in C++17
template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);

// modifiers:
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);

// observers:
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
// 引用计数+1
void __add_shared() _NOEXCEPT {
__libcpp_atomic_refcount_increment(__shared_owners_);
}
// 引用计数-1,如果归0则调用__on_zero_shared
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();
}
// 弱引用计数+1
void __add_weak() _NOEXCEPT {
__libcpp_atomic_refcount_increment(__shared_weak_owners_);
}
// 如果强引用计数归0,则调用__release_weak
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;
};

// 弱引用计数-1,如果归0,则调用__on_zero_shared_weak
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();
}

// 如果强引用计数没有归0,则强引用计数+1
__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;
};

// 强引用计数归0时,进行销毁,将维护的指针交给删除器进行删除,然后调用删除器的析构销毁删除器
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();
}

// 弱引用计数归0时,销毁分配器
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_就是维护的指针

1
element_type*      __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); // 如果p继承了enable_shared_from_this,则保存一份weak_ptr在enable_shared_from_this中
}

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(); // 引用计数+1
}

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(); // 如果weak_ptr为空,则抛出异常
}

析构函数

1
2
3
4
5
6
template<class _Tp>
shared_ptr<_Tp>::~shared_ptr()
{
if (__cntrl_)
__cntrl_->__release_shared(); // 引用计数-1
}

赋值函数

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); // 旧引用计数-1,新引用计数+1
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); // 旧引用计数-1,新引用计数不变
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); // unique_ptr放弃控制,新引用计数==1
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); // 旧引用计数-1,新引用计数==0
}

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,新引用计数==1
}

工厂函数

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)...); // 创建Tp对象,创建引用计数块
auto __control_block = __guard.__release_ptr();
return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block)); // 创建shared_ptr
}

类型转换

对shared_ptr内的指针进行类型转换

1
2
3
4
5
6
7
8
9
template<class _Tp, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
shared_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_VISIBILITY
shared_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_; // shared_ptr创建后,会保存一份weak_ptr在这里
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_);} // 返回共享的shared_ptr,(weak_ptr如果没有初始化则会抛出异常)
_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 // _LIBCPP_STD_VER > 14

template <class _Up> friend class shared_ptr;
};