enable_shared_from_this 解决什么问题
需要在内部使用this的情况,例如回调参数是this, 可以shared_from_this
原理是创建一个weak_ptr, 调用shared_from_this 的时候,返回以weak_ptr为参数的构造shared_ptr 就可以和 weak_ptr 共享sp_count_base 指针,这样所有从shared_from_this返回的ptr 都处于共享状态
1、创建对象 继承std::enable_shared_from_this,使用类中 _M_weak_this 是无效
2、创建一个新的shared_ptr 的时候,会调用__enable_shared_from_this_helper 设置当前对象的_M_weak_this
3、然后在调用shared_from_this 的使用就会和已经共享的对象共享了,也就是_refercount;
enable_shared_from_this
__shared_ptr<_Tp, _Lp>
shared_from_this()
{ return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
void
_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
{ _M_weak_this._M_assign(__p, __n); }
template<typename _Tp1>
friend void
__enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
const __enable_shared_from_this* __pe,
const _Tp1* __px) noexcept
{
if (__pe != 0)
__pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
}
shared_ptr
template<typename _Tp1>
explicit __shared_ptr(_Tp1* __p)
: _M_ptr(__p), _M_refcount(__p)
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
static_assert( !is_void<_Tp1>::value, "incomplete type" );
static_assert( sizeof(_Tp1) > 0, "incomplete type" );
__enable_shared_from_this_helper(_M_refcount, __p, __p);
}
template<typename _Tp1>
explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
: _M_refcount(__r._M_refcount) // may throw
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// It is now safe to copy __r._M_ptr, as
// _M_refcount(__r._M_refcount) did not throw.
_M_ptr = __r._M_ptr;
}
场景
1、主要是场景 类内部异步回调,使用this的问题。外部使用或者依赖注入的情况。
class Foo {
public:
void Bar(std::function<void(Foo*)> callback) {
//异步调用使用this
callback(this);
//有可能出现this 被释放的情况
}
void Bar(std::function<void(std::shared_ptr<Foo>)> callback) {
auto pFoo = shared_from_this();
}
}
一个类型的指针T*, 在类函数中需要返回ptr ,如果返回shared_ptr (this); 会导致生成新的对象,会导致2次释放。
所以也就是这个指针在创建时候已经就有一个share_ptr 进行管理了
#include <memory>
#include <iostream>
class Bad
{
public:
std::shared_ptr<Bad> getptr() {
return std::shared_ptr<Bad>(this);
}
~Bad() { std::cout << "Bad::~Bad() called" << std::endl; }
};
struct Good : std::enable_shared_from_this<Good> // 注意:继承
{
public:
std::shared_ptr<Good> getptr() {
return shared_from_this();
}
~Good() { std::cout << "Good::~Good() called" << std::endl; }
};