std::enable_shared_from_this作用:判断异步回调宿主生命周期

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 有两点需要注意:

  1. weak_from_this() 最好在对象构造时就保存,避免对象被销毁了才weak_from_this(),这时候会触发weak_ptr构造异常
    2.weak_from_this() 返回的 std::weak_ptr 不可作为类成员,因为对象销毁的时候,成员也销毁了,如果这时候访问 std::weak_ptr 肯定会触发异常
    weak_ptr的lock()函数方法的功能是:判断weak_ptr所指向的shared_ptr对象是否存在。若存在,则这个lock方法会返回一个指向该对象的shared_ptr指针;若它所指向的这个shared_ptr对象不存在,则lock()函数会返回一个空的shared_ptr。
#include <iostream>
#include <thread>
#include <functional>
#include <memory>
#include <string>
 class A : public std::enable_shared_from_this<A>
{
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<A> ptrA = std::make_shared<A>(); //继承std::enable_shared_from_this类生命周期由shared_ptr托管
		ptrA->Start();
	}//ptrA超出作用域,对象销毁。去掉括号即保证ptrA 不被销毁,可打印出printInfo
	int wait;
	std::cin >> wait;
}

参考文章:
https://blog.csdn.net/linfengmove/article/details/107065634/

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值