std::enable_shared_from_this作用
应用场景:解决异步回调发生时宿主对象销毁的问题,C++提供了lambda表达式和各种异步函数,std::thread,std::async或者其他框架api都提供了异步回调方法。api::get(url,> { //解析response})
回调回来的时候宿主类对象已经销毁了,但是大多数情况下我们再处理网络结果的时候需要用到宿主类对象的一些数据,这就造成了问题,宿主对象已经销毁了,他的成员数据也一起销毁了,继续调用只会导致无法预期的问题。
有三种应对方法:
(1)宿主类销毁后,切断回调和宿主之前的关系.(C++不提供这样的方法,需要自己设计),自己重新设置回调指针为空,调用回调函数的地方判断回调指针为空后就不调用。
(2)如果回调没有回来,延长宿主对象的生命周期,继承std::enable_shared_from_this可以做到这一点,那就是让lambda捕获宿主对象的shared_ptr指针(share_from_this()),这样在回调回来之前宿主对象不会销毁。但宿主对象的生命周期就依赖于这些回调被调用的时间,有些场景不合适。
(3)最好的方式就是检测对象是否销毁,如果销毁就不调用,如果没有继续执行,同样继承std::enable_shared_from_this可以做到这一点。让回调lambda捕获宿主对象的弱引用指针(weak_from_this()),在回调回来以后,检测weak_ptr是否可用,可用则获取shared_ptr保证宿主生命周期,然后执行其他方法。不可用直接返回。
使用 weak_from_this 有两点需要注意:
#include
#include
#include
#include
#include class A : public std::enable_shared_from_this
{
public:A() { std::cout << __FUNCTION__ << std::endl; };~A() { std::cout << __FUNCTION__ << std::endl; };void Start(){auto weak = weak_from_this();std::thread t([weak]() { //捕获宿主弱引用指针std::this_thread::sleep_for(std::chrono::seconds(10));auto self = weak.lock();//weak_ptr所指向的shared_ptr对象不存在会返回空指针,否则返回对象指针if (self) //判断宿主是否销毁{self->PrintSelf();}});t.detach();}void PrintSelf(){std::cout << printInfo << std::endl;}
private:std::string printInfo = " its my self.";
};int main()
{{std::shared_ptr ptrA = std::make_shared(); //继承std::enable_shared_from_this类生命周期由shared_ptr托管ptrA->Start();}//ptrA超出作用域,对象销毁。去掉括号即保证ptrA 不被销毁,可打印出printInfoint wait;std::cin >> wait;
}
参考文章:
https://blog.csdn.net/linfengmove/article/details/107065634/
下一篇:kettle—数据库配置