我们创建了一个类的对象,同时让std::shared_ptr来管理这个对象,如果此时我们需要传递该对象给其他地方使用时,我们也需要使用std::shared_ptr来传递这个对象.
这里有一小段代码
class c_A {
public:
~c_A() {
std::cout << "c_A destructor\n";
}
};
int main_c_A() {
c_A* c_a = new c_A();
std::shared_ptr<c_A> sharedPtr_c_a(c_a);
std::shared_ptr<c_A> sharedPtr_c_a2(c_a);
std::cout << "sharedPtr_c_a : " << sharedPtr_c_a.use_count() << "\n";
std::cout << "sharedPtr_c_a2 : " << sharedPtr_c_a2.use_count() << "\n";
return 0;
}
这段代码的运行结果很容易知道.
sharedPtr_c_a : 1
sharedPtr_c_a2 : 1
c_A destructor
c_A destructor
运行结果是崩了,毕竟一个类被析构了两次.两个shared_ptr彼此独立,虽然都指向c_a,但是自己的引用计数都是1
正常应该是
std::shared_ptr<c_A> sharedPtr_c_a2 = sharedPtr_c_a;
这样就可以彼此有点关联,引用计数不再是1,而是2.
如果有这么一个类, 当类对象被share_ptr管理,且在类的成员函数里需要把当前类对象作为参数传给其他函数时,就需要传递一个指向自身的share_ptr.
class c_C : public std::enable_shared_from_this<c_C> {
public:
std::shared_ptr<c_C> getSharedPtr() {
return std::shared_ptr<c_C>(this);
}
~c_C() {
std::cout << "c_C destructor\n";
}
};
int main_c_C() {
c_C* c_c = new c_C();
std::shared_ptr<c_C> sharedPtr_c_c(c_c);
std::shared_ptr<c_C> sharedPtr_c_c2 = sharedPtr_c_c->getSharedPtr();
//std::shared_ptr<c_C> sharedPtr_c_b2 = sharedPtr_c_b;
std::cout << "sharedPtr_c_c : " << sharedPtr_c_c.use_count() << "\n";
std::cout << "sharedPtr_c_c2 : " << sharedPtr_c_c2.use_count() << "\n";
return 0;
}
这种情况就类似第一部分的代码一样的情况,因为传递的shared_ptr自己维持新的引用,这样的运行结果
sharedPtr_c_c : 1
sharedPtr_c_c2 : 1
c_C destructor
c_C destructor
也是崩了.
所以可以利用C++11的新特性 enable_shared_from_this.
cplusplus.com解释
- 基类如果是std::enable_shared_from_this, 那派生类T可以使用shared_from_this成员函数.
- 这个成员函数的作用就是可以让派生类对象创建一个指向自己的shared_ptr实例,而且就算是已经存在了其他shared_ptr对象,同样会共享所有权,而不是创建不同的所有权分组.
class c_B : public std::enable_shared_from_this<c_B> {
public:
std::shared_ptr<c_B> getSharedPtr() {
return shared_from_this();
}
~c_B() {
std::cout << "c_B destructor\n";
}
};
int main_c_B() {
c_B* c_b = new c_B();
std::shared_ptr<c_B> sharedPtr_c_b(c_b);
//std::shared_ptr<c_B> sharedPtr_c_b2 = c_b->getSharedPtr();
std::shared_ptr<c_B> sharedPtr_c_b2 = sharedPtr_c_b;
std::cout << "sharedPtr_c_b : " << sharedPtr_c_b.use_count() << "\n";
std::cout << "sharedPtr_c_b2 : " << sharedPtr_c_b2.use_count() << "\n";
return 0;
}
sharedPtr_c_b : 2
sharedPtr_c_b2 : 2
Hello, World!
c_B destructor
Process finished with exit code 0
程序运行,成功退出,不崩溃了
这里有一句"注意,简单地返回shared_ptr(this)会有问题,因为这会创建一个不同的所有权组."