购物手机网站怎么做,设计一个学院网站,网站建设黄页,wordpress访问许可文章目录 enable_shared_from_this定义使用场合源码实现注意 enable_shared_from_this定义
定义于头文件
template class T class enable_shared_from_this; (C11 起) std::enable_shared_from_this 能让其一个对象#xff08;假设其名为 t #xff0c;且已被一… 文章目录 enable_shared_from_this定义使用场合源码实现注意 enable_shared_from_this定义
定义于头文件
template class T class enable_shared_from_this; (C11 起) std::enable_shared_from_this 能让其一个对象假设其名为 t 且已被一个 std::shared_ptr 对象 pt 管理安全地生成其他额外的 std::shared_ptr 实例假设名为 pt1, pt2, … 它们与 pt 共享对象 t 的所有权。
若一个类 T 继承 std::enable_shared_from_this 则会为该类 T 提供成员函数 shared_from_this。当 T 类型对象 t 被一个为名为 pt 的 std::shared_ptr 类对象管理时调用 T::shared_from_this 成员函数将会返回一个新的 std::shared_ptr 对象它与 pt 共享 t 的所有权。
使用场合
需要在类对象的内部中获得一个指向当前对象的 shared_ptr 对象。通过类的成员函数安全的获取对象的this指针一般来说我们不建议直接返回this指针可以想象下有这么一种情况返回的this指针保存在外部一个局部/全局变量当对象已经被析构了但是外部变量并不知道指针指向的对象已经被析构了如果此时外部使用了这个指针就会发生程序奔溃。
崩溃示例
#include iostream
#include memoryclass Foo{
public:Foo(){std::cout Foo::Foo constructor run std::endl;}~Foo(){std::cout Foo::~Foo destructor run std::endl;}std::shared_ptrFoo GetSharedObject(){return std::shared_ptrFoo(this);}
};int main()
{std::shared_ptrFoo p(new Foo());std::shared_ptrFoo q p-GetSharedObject();std::cout p.use_count() std::endl;std::cout q.use_count() std::endl;return 0;
}程序运行输出
Foo::Foo constructor run
1
1
Foo::~Foo destructor run
Foo::~Foo destructor run从程序运行输出看出析构函数调用了2次这明显跟我们的预期不符。
借助指针指针可以很轻松的解决这个问题
#include iostream
#include memoryclass Foo : public std::enable_shared_from_thisFoo
{
public:Foo(){std::cout Foo::Foo constructor run std::endl;}~Foo(){std::cout Foo::~Foo destructor run std::endl;}std::shared_ptrFoo GetSharedObject(){return shared_from_this();}
};int main()
{std::shared_ptrFoo p(new Foo());std::shared_ptrFoo q p-GetSharedObject();std::cout p.use_count() std::endl;std::cout q.use_count() std::endl;return 0;
}程序运行输出
Foo::Foo constructor run
2
2
Foo::~Foo destructor run源码实现
templatetypename _Tp
class enable_shared_from_this
{
protected:enable_shared_from_this() { }enable_shared_from_this(const enable_shared_from_this) { }enable_shared_from_thisoperator(const enable_shared_from_this){ return *this; }~enable_shared_from_this() { }public:shared_ptr_Tpshared_from_this(){ return shared_ptr_Tp(this-_M_weak_this); }shared_ptrconst _Tpshared_from_this() const{ return shared_ptrconst _Tp(this-_M_weak_this); }private:/***brief _M_weak_assign函数在类型T被包覆在shared_ptr的过程中会被调用*/templatetypename _Tp1void_M_weak_assign(_Tp1* __p, const __shared_count __n) const{ _M_weak_this._M_assign(__p, __n); }templatetypename _Tp1friend void__enable_shared_from_this_helper(const __shared_count __pn,const enable_shared_from_this* __pe,const _Tp1* __px){if (__pe ! 0)__pe-_M_weak_assign(const_cast_Tp1*(__px), __pn);
}mutable weak_ptr_Tp _M_weak_this; // const函数也可以修改该变量
};/***brief 共享智能指针*/
templatetypename _Tp
class shared_ptr
: public __shared_ptr_Tp
{
public:shared_ptr(): __shared_ptr_Tp() { }// ...
};templatetypename _Tp, _Lock_policy _Lp
class __shared_ptr
{
public:typedef _Tp element_type;__shared_ptr(): _M_ptr(0), _M_refcount() // never throws{ }// 智能指针构造会调用__enable_shared_from_this_helpertemplatetypename _Tp1explicit__shared_ptr(_Tp1* __p)
: _M_ptr(__p), _M_refcount(__p){__glibcxx_function_requires(_ConvertibleConcept_Tp1*, _Tp*)typedef int _IsComplete[sizeof(_Tp1)];__enable_shared_from_this_helper(_M_refcount, __p, __p);
}//...
};
注意
enable_shared_from_this 其内部保存着一个对 this 的弱引用例如 std::weak_ptr )。 std::shared_ptr 的构造函数检测无歧义且可访问的 (C17 起) enable_shared_from_this 基类并且若内部存储的弱引用未为生存的 std::shared_ptr 占有则 (C17 起)赋值新建的 std::shared_ptr 为内部存储的弱引用。为已为另一 std::shared_ptr 所管理的对象构造一个 std::shared_ptr 将不会考虑内部存储的弱引用从而将导致未定义行为。
只允许在先前已被std::shared_ptr 管理的对象上调用 shared_from_this 。否则调用行为未定义 (C17 前)抛出 std::bad_weak_ptr 异常通过 shared_ptr 从默认构造的 weak_this 的构造函数 (C17 起)。
enable_shared_from_this 提供安全的替用方案以替代 std::shared_ptr(this) 这样的表达式这种不安全的表达式可能会导致 this 被多个互不知晓的所有者析构。