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