首先概括一下shared_from_this
的作用:可以在类的成员函数中直接通过this
得到指向当前所在对象的shared_ptr
的智能指针,具体操作如下。
使用方法
设需要提供shared_from_this
方法的类为C0
定义为类,首先需要将C0
定义为 std::enable_shared_from_this<C0>
的派生类,然后C0
就继承了shared_from_this
这个方法,示例如下:
class C0 : public std::enable_shared_from_this<C0> {
public:shared_ptr<C0> get_shared() {return shared_from_this();}
};
示例中类C0
的对象中可以通过get_shared
返回一个指向当前对象的智能指针,测试如下:
int main() {shared_ptr<C0> tp1 = make_shared<C0>(), p1 = tp1->get_shared();assert(p1.use_count() == 2);
}
防止 this 提前被释放
直接看一个例子:
class C1 {
public:int *val = new int(1);void test() {auto x = thread([this]() {sleep(1);if (this->val)cout << "in thread, *this->val: " << *this->val << endl;elsecout << "in thread, this->val is null" << endl;});x.detach();//主线程不等待x线程结束}~C1() {delete val;val = nullptr;cout << "~C1()" << endl;}
};int main() {{shared_ptr<C1> obj = make_shared<C1>();obj->test();}//obj生命周期结束sleep(2);
}
运行结果如下:
在创建的子线程x
中暂停1秒后,主线程已从test()
返回,之后obj
生命周期结束,obj
指向的对象被释放,所以子线程x
执行的匿名函数捕获的this
已经被释放。
再看一个使用shared_from_this
防止this
被释放的例子:
class C2 : public std::enable_shared_from_this<C2> {
public:int *val = new int(1);void test() {auto x = thread([self = shared_from_this()]() {sleep(1);if (self->val)cout << "in thread, *self->val: " << *self->val << endl;elsecout << "in thread, self->val is null" << endl;});x.detach();}~C2() {delete val;val = nullptr;cout << "~C2()" << endl;}
};int main() {{shared_ptr<C2> obj = make_shared<C2>();obj->test();}sleep(2);
}
运行结果如下:
与之前不同的是,子线程x
执行的匿名函数捕获列表中定义了一个指向this
的智能指针self
,这样即使主线程中的智能指针obj
生命周期结束,obj
指向的对象也不会释放,从子线程的角度来看就避免了 this
提前被释放的问题。
参考:
https://stackoverflow.com/questions/712279/what-is-the-usefulness-of-enable-shared-from-this
https://en.cppreference.com/w/cpp/language/lambda