Question:有一个类,这个类的对象是使用shared_ptr 管理的,在类内某个成员函数里,我们需要获取指向当前对象的 shared_ptr,应该如何获取?

可能的答案 1:

1
2
3
4
5
6
class A {
public:
std::shared_ptr<A> get_ptr() {
return std::shared_ptr<A>(this); // 返回 this 指针的 shared_ptr
}
};

但是这样做是不安全的。在 get_ptr 中,会根据 this 指针创建一个完全独立的新的std::shared_ptr,这个 shared_ptr 有自己的引用计数,完全独立于当前类对象的 shared_ptr;这时这两个 shared_ptr 是同时在管理这个对象,如果新的这个shared_ptr 计数清零,它会尝试删除这个对象,造成未定义的行为。

正确的做法就是使用std::enable_shared_from_this

std::enable_shared_from_this是一个模板类,可以在类的内部,安全的获取自身对象的 shared_ptr。

在线试一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<memory>
#include<iostream>

class A : public std::enable_shared_from_this<A> {
public:
std::shared_ptr<A> ptr;

A() { std::cout << "A constructor" << std::endl; }
~A() { std::cout << "A destructor" << std::endl; }

std::shared_ptr<A> show() { return shared_from_this(); }
};

int main() {
std::shared_ptr<A> a(new A);
std::cout << "a: " << a.use_count() << std::endl;
std::shared_ptr<A> b = a->show();
std::cout << "a: " << a.use_count() << ", b: " << b.use_count() << std::endl;
return 0;
}