Skip to content

Instantly share code, notes, and snippets.

@haxpor
Created July 9, 2019 04:36
Show Gist options
  • Save haxpor/99d82051235b1c10868bb131be8874be to your computer and use it in GitHub Desktop.
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.
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