首先概括一下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;
else
cout << "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;
else
cout << "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