首页 > 代码库 > C++学习之路: share_from_this<T>类的使用

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指针析构完所持有的对象后,再自己 

 

C++学习之路: share_from_this<T>类的使用