zoukankan      html  css  js  c++  java
  • C++学习之路: share_from_this<T>类的使用

    引言: 当我们在类的内部需要定义一个指向 this 自身对象的 智能指针时, 会出现 两个同指向智能指针 分属两个系统的问题, 导致析构的时候 出现二次析构, 程序就会挂掉。

    因为两个指针指向同一个对象,但是却不共享引用计数

    那么在类内部如何获取 指向自身对象的 智能指针呢, 显式手动的获取很明显是错误的;

    这时就需要在类 A 定义时继承一个 enable_share_from_this<A>  类即可

    这样在类的内部就可以获取指向 自身的智能指针, 且影响其他智能指针的引用计数;

    在类内部用 share_from_this() 获取智能指针可以 让类外部的 智能指针知道, 使其所有共对象的智能指针 共享计数,  文字描述十分绕, 我们看了代码就十分明了了;

    1.举个例子,下面的代码在函数f内部通过this构造了shared_ptr对象,然后打印x_的值。

     1 class B { 
     2 public: 
     3     B(): x_(4) { 
     4         cout << "B::B()" << endl; 
     5     } 
     6      
     7     ~B() { 
     8         cout << "B::~B()" << endl; 
     9     } 
    10      
    11     void f() { 
    12         shared_ptr<B> p(this); //显式的 用this 初始化一个指向自身的智能指针, 外部的其他智能指针并不知情, 他们不共享引用计数。
    13         cout << p->x_ << endl; //
    14         //shared_from_this(); 
    15     } 
    16      
    17 private: 
    18     int x_; 
    19 }; 

    以下是测试代码:

    1 int main(int argc, char** argv) { 
    2     shared_ptr<B> x(new B);  //类外部的智能指针 不知情类内部有相同的指针
    3     x->f(); 
    4     return 0; 
    5 } 

    打印结果:

    1 B::B() 
    2 4 
    3 B::~B() 
    4 B::~B() 
    5 //两次析构B对象,这是个灾难。

    显然两个同指向的 智能指针如果不共享计数的话, 会引起两次析构的巨大灾难;  

     

    2. enable_shared_from_this<T> 这个类就是专门为解决这个问题而产生的

    注意继承时要 定义为 public,否则外部无法使用。

     1 class A : public enable_shared_from_this<A> { 
     2 public: 
     3     A() { 
     4         cout << "A::A()" << endl; 
     5     } 
     6      
     7     ~A() { 
     8         cout << "A::~A()" << endl; 
     9     } 
    10      
    11     void f() { 
    12         //cout << shared_from_this()->x_ << endl; // this way is okay too 
    13         shared_ptr<A> p = shared_from_this(); 
    14         cout << p->x_ << endl; 
    15     } 
    16      
    17 private: 
    18     int x_; 
    19 }; 

    测试代码

    1 int main(int argc, char** argv) { 
    2     shared_ptr<A> x(new A); 
    3     x->f(); 
    4     return 0; 
    5 } 

    打印结果

    1 A::A() 
    2 0 
    3 A::~A() 
    4 //只出现了一次析构

    显然, 类内部的智能指针和 类外部的智能指针共享了 引用计数,  从析构角度来看, main函数结束  需要析构A智能指针,  则A调用自己的析构函数 去析构对象 , 那么首先析构的是 对象中智能指针B,

    B析构了后 引用计数-1, 然后main中的A指针析构完所持有的对象后,再自己 

  • 相关阅读:
    连接过滤器
    插件使用 之 Bmap
    插件使用 之 ztree、nicescroll
    插件使用 之 layui、echart
    插件使用 之 bootstrap
    jquery显隐特效 动画 事件
    jquery js对比 加载 操作内容 属性 样式 元素 选择器
    js三级联动练习(地址填写)
    js时间、定时器、移动div块、轮播
    js DOM操作
  • 原文地址:https://www.cnblogs.com/DLzhang/p/4043527.html
Copyright © 2011-2022 走看看