目录
1、 _Sp_counted_base<_Lp>* _M_pi;
3、__weak_count(const __weak_count<_Lp>& __r) noexcept
一、关键点解析
1、 _Sp_counted_base<_Lp>* _M_pi;
__shared_count用于shared_ptr,__weak_count用于weak_ptr, __weak_count和__shared_count共用_Sp_counted_base类型指针
2、__weak_count(const __shared_count<_Lp>& __r) noexcept
__weak_count(const __shared_count<_Lp>& __r) noexcept//构造函数
: _M_pi(__r._M_pi)
{
if (_M_pi != 0)
_M_pi->_M_weak_add_ref(); //增加weak count
}
static inline void
__attribute__ ((__unused__))
__atomic_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
__atomic_add(__mem, __val);
else
__atomic_add_single(__mem, __val);
#else
__atomic_add_single(__mem, __val);
#endif
}
void
_M_weak_add_ref() noexcept
{ __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
__shared_count作为参数构造__weak_count,两者共用的_Sp_counted_base的weak count加1。
3、__weak_count(const __weak_count<_Lp>& __r) noexcept
__weak_count(const __weak_count<_Lp>& __r) noexcept
: _M_pi(__r._M_pi)
{
if (_M_pi != 0)
_M_pi->_M_weak_add_ref();
}
__weak_count作为参数构造__weak_count,_Sp_counted_base的weak count加1。
二、源码分析
template<_Lock_policy _Lp>
class __weak_count
{
public:
constexpr __weak_count() noexcept : _M_pi(0) //常构造函数
{ }
__weak_count(const __shared_count<_Lp>& __r) noexcept//构造函数
: _M_pi(__r._M_pi)
{
if (_M_pi != 0)
_M_pi->_M_weak_add_ref(); //增加weak count
}
__weak_count(const __weak_count<_Lp>& __r) noexcept//构造函数
: _M_pi(__r._M_pi)
{
if (_M_pi != 0)
_M_pi->_M_weak_add_ref();
}
~__weak_count() noexcept
{
if (_M_pi != 0)
_M_pi->_M_weak_release();
}
__weak_count<_Lp>&
operator=(const __shared_count<_Lp>& __r) noexcept
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != 0)
__tmp->_M_weak_add_ref();
if (_M_pi != 0)
_M_pi->_M_weak_release();
_M_pi = __tmp;
return *this;
}
__weak_count<_Lp>&
operator=(const __weak_count<_Lp>& __r) noexcept
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != 0)
__tmp->_M_weak_add_ref();
if (_M_pi != 0)
_M_pi->_M_weak_release();
_M_pi = __tmp;
return *this;
}
void
_M_swap(__weak_count<_Lp>& __r) noexcept
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
__r._M_pi = _M_pi;
_M_pi = __tmp;
}
long
_M_get_use_count() const noexcept
{ return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
bool
_M_less(const __weak_count& __rhs) const noexcept
{ return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
bool
_M_less(const __shared_count<_Lp>& __rhs) const noexcept
{ return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
// Friend function injected into enclosing namespace and found by ADL
friend inline bool
operator==(const __weak_count& __a, const __weak_count& __b) noexcept
{ return __a._M_pi == __b._M_pi; }
private:
friend class __shared_count<_Lp>;
_Sp_counted_base<_Lp>* _M_pi;
};
// Now that __weak_count is defined we can define this constructor:
template<_Lock_policy _Lp>
inline
__shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
: _M_pi(__r._M_pi)
{
if (_M_pi != nullptr)
_M_pi->_M_add_ref_lock();
else
__throw_bad_weak_ptr();
}
// Now that __weak_count is defined we can define this constructor:
template<_Lock_policy _Lp>
inline
__shared_count<_Lp>::
__shared_count(const __weak_count<_Lp>& __r, std::nothrow_t)
: _M_pi(__r._M_pi)
{
if (_M_pi != nullptr)
if (!_M_pi->_M_add_ref_lock_nothrow())
_M_pi = nullptr;
}