std::enable_shared_from_this作用:判断异步回调宿主生命周期
创始人
2025-06-01 14:18:42
0

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 
#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/

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...