首先概括一下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