背景
enable_shared_from_this 是 C++11 定义在头文件 include 中的一个模板类,其作用是在类的内部安全的得到 this 指针的 shared_ptr 版本。
获取 this 的 shared_ptr 版本
①.概述
shared_ptr 是通过引用计数来判断对象是否可以被销毁。
②.通过 this 创建 shared_ptr
多次通过原始指针创建 shared_ptr 不会增加引用计数,且会造成内存重复释放。
class demoClass
{
public:
demoClass(){ cout << "demoClass 构构" << endl; }
~demoClass(){ cout << "demoClass 析构" << endl; }
void func()
{
shared_ptr<demoClass> sp(this);
cout << "当前引用计数 " << sp.use_count() << endl;
}
};
int main()
{
demoClass* demo = new demoClass;
shared_ptr<demoClass> sp(demo);
cout << "当前引用计数 " << sp.use_count() << endl;
demo->func();
system("pause");
return 0;
}
③.继承 enable_shared_from_this 实现
class demoClass: public enable_shared_from_this<demoClass>
{
public:
demoClass(){ cout << "demoClass 构构" << endl; }
~demoClass(){ cout << "demoClass 析构" << endl; }
void func()
{
shared_ptr<demoClass> sp = shared_from_this();
cout << "当前引用计数 " << sp.use_count() << endl;
}
};
int main()
{
demoClass* demo = new demoClass;
shared_ptr<demoClass> sp(demo);
cout << "当前引用计数 " << sp.use_count() << endl;
demo->func();
return 0;
}
类的内部异步使用 this 指针
①.概述
使用 std::async 可以开启一个异步任务,返回一个 std::future 对象。需要注意的是 std::future 对象的析构函数会等待异步操作的完成。
②.异步回调中使用 this 指针
若在异步任务执行期间该对象已经被释放,则会出错。
class demoClass
{
public:
demoClass(){ cout << __FUNCTION__ << endl; }
~demoClass(){ cout << __FUNCTION__ << endl; }
public:
void func()
{
cout << __FUNCTION__ << endl;
this_thread::sleep_for(chrono::seconds(5));
cout << msg << endl;
}
void asyncFunc(future<void> & f )
{
f = async(launch::async, bind(&demoClass::func, this ));
cout << __FUNCTION__ << endl;
}
private:
string msg = "hello world";
};
future<void> m_future;//为确保真的异步
int main()
{
{
shared_ptr<demoClass> demo(new demoClass);
demo->asyncFunc(m_future);
}//释放 demo
cout << __FUNCTION__ << endl;
m_future.wait();
return 0;
}
③.使用 shared_from_this 延长对象生命周期
class demoClass : public enable_shared_from_this<demoClass>
{
public:
demoClass(){ cout << __FUNCTION__ << endl; }
~demoClass(){ cout << __FUNCTION__ << endl; }
public:
void func()
{
cout << __FUNCTION__ << endl;
this_thread::sleep_for(chrono::seconds(5));
cout << msg << endl;
}
void asyncFunc(future<void> & f )
{
f = async(launch::async, bind(&demoClass::func, shared_from_this() ));
cout << __FUNCTION__ << endl;
}
private:
string msg = "hello world";
};
future<void> m_future;
int main()
{
{
shared_ptr<demoClass> demo(new demoClass);
demo->asyncFunc(m_future);
}
cout << __FUNCTION__ << endl;
m_future.wait();
return 0;
}
注意事项
继承自 enable_shared_from_this 类可以安全的得到 this 的 shared_ptr 版本,关键在于其 private 的 weak_ptr 变量 ,因此在使用时必须注意以下两点
①.必须 public 继承自 enable_shared_from_this,只有public 继承才可以继承父类的 private 成员。
②.必须使用 shared_ptr 来管理对象,确保 weak_ptr 变量被初始化。