Created
July 9, 2019 04:36
-
-
Save haxpor/99d82051235b1c10868bb131be8874be to your computer and use it in GitHub Desktop.
section of code showing why shared_ptr has flaw when using raw pointer as input in constructor, because it won't increase the reference count. Only when send in shared_ptr via copy constructor, and assignment operator, will it increase reference count.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
// 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(); } | |
// 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; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment