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

本文探讨了在C++中使用智能指针时遇到的一个常见问题:如何避免因多个智能指针指向同一对象而导致的二次析构问题。介绍了enable_shared_from_this模板类的正确使用方法,确保所有智能指针能够共享引用计数。

引言: 当我们在类的内部需要定义一个指向 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指针析构完所持有的对象后,再自己 

 

转载于:https://www.cnblogs.com/DLzhang/p/4043527.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值