C++ 中 enable_shared_from_this 的使用总结

2023-11-06

背景

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 变量被初始化。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 中 enable_shared_from_this 的使用总结 的相关文章

  • ASP Core HttpClientFactory 模式使用客户端证书

    任何人都知道在使用时如何使用客户端证书HttpClientFactory 在我发现的所有示例中 您需要提供HttpMessageHandler in the HttpClient构造函数 使用时不可用HttpClientFactory se
  • C# 测试活动的互联网连接。 Ping google.com

    C 2008 我正在使用此代码来测试互联网连接 因为我的应用程序必须登录到网络服务器 但是 如果用户互联网连接失败或电缆被拔出 我必须通知用户 Ping www google com to check if the user has a i
  • binary_log_types.h:没有这样的文件或目录

    我正在编译一个小型 mysql C 项目并且 遇到以下错误 C Program Files x86 MySQL MySQL Server 5 7 include mysql com h 22 30 fatal error binary lo
  • 如何通知父线程所有子线程都已终止?

    我有一个控制台应用程序正在移植到 WPF 该应用程序有 3 个工作线程 在将一些输出结果打印到屏幕上之前 这些线程都连接到主线程 我的理解是 如果我尝试在 WPF 应用程序中执行相同的操作 GUI 将被阻止并且不会响应用户 那么如何通知父线
  • C# 并行与并行线程代码性能

    我一直在测试 System Threading Parallel 与线程的性能 我很惊讶地发现并行比线程花费更长的时间来完成任务 我确信这是由于我对并行的了解有限 我刚刚开始阅读 我想我会分享一些片段 如果有人可以向我指出并行代码比线程代码
  • WPF Dispatchertimer 延迟反应/冻结

    在我的 WPF 应用程序中 我使用 3 个不同的 DispatcherTimers 一种是用于显示当前时间 一种是每 5 秒运行一次数据库查询 第三个每 1 秒刷新一次自定义按钮的值 当我的程序运行时 有很多延迟 冻结 例如 时间开始正确计
  • 计算复杂数组的abs()值的最快方法

    我想计算 C 或 C 中复杂数组元素的绝对值 最简单的方法是 for int i 0 i lt N i b i cabs a i 但对于大向量来说 速度会很慢 有没有办法加快速度 例如使用并行化 语言可以是 C 或 C 鉴于所有循环迭代都是
  • NHibernate IQueryable 集合作为 root 的属性

    我有一个根对象 它有一个集合属性 例如 I have a Shelf object that has Books Now public class Shelf public ICollection
  • 通过用于 Symbol 条码扫描仪 DS4208 的 SNAPI.dll API 捕获图像

    我想通过 SNAPI API 从 Symbol 目前为 Zebra 条形码扫描仪 DS4208 型号 我们还使用 Zebra 的另一个但兼容的型号 捕获图像 条形码捕获 识别效果很好 但看起来像SnapiDLL SNAPI SnapShot
  • 试图使用加密来混淆我的项目打破了它

    我试图尝试不同的混淆选项 为了做到这一点 我首先尝试了加密货币 以下是我遵循的步骤 打开加密向导并选择一些选项 选择我的解决方案文件 完成向导后 我看到有些 Dll 被很好地混淆了 但我的项目现在无法构建 我注意到的两件事是 我的文件夹中有
  • EF Core 一对多关系列表返回 null

    我正在尝试学习如何在 EF Core 中正确利用 DbContext 我有一个团队课程 public class Team public int ID get set public string Name get set public bo
  • Nuget - 对象引用未设置为对象的实例

    我在 vs 2015 中遇到了 nuget 包管理器的问题 像Unity这样的一些包已经安装没有问题了 某些软件包 例如 EF 在安装时出现问题 像 Automapper 这样的一些软件包也有同样的问题 但是当我安装这个软件包的另一个版本时
  • C++:LPWSTR 在 cout 中打印为地址

    我有一个类型变量LPTSTR 我打印到std cout with lt lt 在 ANSI 系统中 不知道它是在哪里确定的 它工作得很好 它打印了字符串 现在 在 Unicode 系统中 我得到的是十六进制地址而不是字符串 那么 为什么LP
  • 类型别名和不完整类型

    我可能已经超出了解决这个本应简单的问题的范围 我在这里开始这个问题 在编译时获取基类的类型 https stackoverflow com questions 17735852 getting type of a base class at
  • 如何在 Visual Studio 2010 Express 中引用 system.drawing?

    我对此有点陌生 我的印象是要绘制我创建的矩形 我需要使用 system drawing graphics 问题是 我收到错误 命名空间 System 中不存在类型或命名空间名称 drawing 您是否缺少程序集引用 当我右键单击解决方案资源
  • 如何在asp.net core 6中注入IConfiguration

    web api 应用程序中不再有 Startup cs 我们以前可以注入IConfiguration进入那个Startup class public class Startup public Startup IConfiguration c
  • 使用非字符串作为字符串(而不是自动使用 ToString)时如何显示错误?

    建议的重复确实是一个类似的问题 然而 答案只涵盖一种选择 禁用 ToString 本身 还有其他可能的解决方案 例如让 Visual Studio 警告我 或者不调用 ToString 仔细阅读那里的答案 他认为is调用 只是解释说没有办法
  • C++ 联合数组和变量?

    在C 中没有办法做这样的事情吗 union Scalar x y Scalar v 2 Where x v 0 and y v 1 既然您使用的是 C 而不是 C 并且它们具有相同的类型 为什么不直接将 x 设为对 v 0 的引用 将 y
  • 如何创建和使用类箭头运算符? [复制]

    这个问题在这里已经有答案了 因此 在到处研究之后 我似乎找不到如何创建类箭头运算符 即 class Someclass operator gt 我只需要知道如何使用它并正确使用它 它的输入是什么 它返回什么 我如何正确地声明 原型化它 运算
  • DataGridView 捕获用户行选择

    我在处理选择时遇到问题DataGridView 我的网格视图包含一个金额列 表单上有一个文本框 应显示所选网格视图行的总数 因此 我需要在用户选择 取消选择 gridview 行时捕获事件并相应地计算 添加 减去 金额 我找到了两种方法 使

随机推荐

  • java 类增强机制

    前言 对类的增强有多少种方式 我们首先想一下一个类的生命周期 从编码到程序运行结束 对类的增强 目的是为了在使用的时候能够在类原有的行为上进行增强 所以编码一直到使用中的几乎每个环节都可以对类进行增强 主要有以下几种方式 静态代理 编译期织
  • 遇到文件误删情况,使用EasyRecovery快速恢复

    当我们不小心将文件误删了 还有办法恢复吗 可能很多朋友认为这是不可能的 一个连在电脑中都无法找到痕迹的文件 我们要怎么找到它呢 其实也不是不可能 借助专业的数据恢复软件EasyRecovery就可以帮你恢复彻底删除的文件 下面就一起来学习具
  • 【Netty】NIO基础(三大组件、文件编程)

    文章目录 三大组件 Channel Buffer Selector ByteBuffer ByteBuffer 正确使用姿势 ByteBuffer 内部结构 ByteBuffer 常见方法 分配空间 向 buffer 写入数据 从 buff
  • k-近邻算法的Python实现

    k 近邻算法的Python实现 一 概述 k 近邻算法 k Nearest Neighbour algorithm 又称为KNN算法 是数据挖掘技术中原理最简单的算法 KNN的工作原理 给定一个已知标签类别的训练数据集 输入没有标签的新数据
  • Netty网络编程框架

    一 简介 Netty是由JBOSS提供的一个java开源框架 Netty提供异步的 事件驱动的网络应用程序框架和工具 用以快速开发高性能 高可靠性的网络服务器和客户端程序 也就是说 Netty 是一个基于NIO的客户 服务器端编程框架 使用
  • B3:多个if(c++)

    做纸箱最少需要多少面积的硬纸板 题目描述 请问做一个尺寸为a b c 单位 厘米 的开口的立方体纸箱 只有一个面是不需要封的 其余5个面都需要封起来 这样算开口的 最少需要多少平方厘米的纸 6 1 6 输入 三个整数 abc 输出 制作该纸
  • Javascript中的every()与some()的区别和应用

    every 定义和用法 every 方法用于检测数组所有元素是否都符合指定条件 通过函数提供 every 方法使用指定函数检测数组中的所有元素 如果数组中检测到有一个元素不满足 则整个表达式返回 false 且剩余的元素不会再进行检测 如果
  • 遗传的效应,美貌与智慧奇妙的遗传

    身高是母亲的遗传大 在营养状况下的前提下 父母的遗传是决定孩子身高的主要因素 其中妈妈的身高尤其关键 妈妈长得高 孩子也大多长得比较高 智力是母亲的遗传大 智力有一定的遗传性 同时受到环境 营养 教育等后天因素的影响 据科学家评估 遗传对智
  • 南大通用&河北工业大学人工智能与数据科学学院党支部共建暨研究生培养基地合作签约仪式顺利举办

    2022年2月18日下午 天津南大通用数据技术股份有限公司 河北工业大学人工智能与数据科学学院党支部共建签约仪式暨研究生培养基地签约仪式在普天创新产业园23层会议室举行 南大通用董事长丁明峰 高级副总裁赵伟 总工办主任杨伟伟 人力资源部总监
  • python中有哪些去除重复项的操作

    Python中去除重复项的操作 常用的有以下几种方式 1 使用set 将列表转化为集合 再转化为列表 即可去重 list a 1 2 3 2 1 4 5 4 6 7 7 new list a list set list a print ne
  • JMeter----安装与介绍以及简单页面录制和移动端录制

    1 什么是JMeter 2 JMeter的安装 3 JMeter基本使用 4 JMeter运行原理 5 JMeter录制脚本 1 什么是JMeter JMeter简介 JMeter是Apache公司使用Java平台开发的一套测试工具 JMe
  • flowable实战(三):关于流程图编辑

    发现很多人讲到flowable 就是大概讲一下整合里面一些名词之类 实操偏少 或者用一个小demo演示一下 就完了 但是一涉及到具体的业务 你会发现涉及到工作流要有多麻烦 考虑很多情况进去会涉及到条件设置 逻辑判断甚至官方提供的那么多方法你
  • C++实现人机对战围棋(使用Leela Zero权重)-界面

    1 在 leela zero next 包中有一个 从人类游戏训练的 较弱的 网络的权重文件 https sjeng org zero best v1 txt zip 6残差块 128通道 2 并在 easyx吧 百度贴吧下了一个双人对战的
  • C语言-函数指针-快速排序算法

    概述 使用C语言 实现结构体多元素 排序算法 冒泡排序 这里使用示例 蓝牙信号强度排序解说 编码环境 Visual Studio 2022 1 code include
  • Python int()的有趣用法

    Python中的int 函数相信大家都不陌生 总的来说 就是int 函数用于将字符串或数字转换为整型 那么今天要说的有趣用法是什么呢 先看一行代码 并猜一下它有什么作用 int 1 200 2 初看这行代码想半天也没搞懂 于是help in
  • 2014年12月4日星期四(DEMO10-2地形生成函数)

    转眼间 2014年快过去了 数了数代码 封装后的代码也有17000行了 但是 还有很多工作量 继续进行最为敬畏的地形生成 这个DEMO的意思是说 加载256色位图 以位图颜色索引乘以一个缩放因子为高程 将每个单元格分割为三角形 并插入到物体
  • 西瓜书《机器学习》课后答案——chapter5_5.5

    网络结构 这里采用简单的单隐层神经网络 输入层有2个神经元 隐层有4个神经元 输出层有2个神经元 隐层采用sigmoid激活函数 输出层采用softmax激活函数 z1 W1x b1 boldsymbol z 1 W 1 boldsymbo
  • Flutter之自动更新(自带源码 包看包会)

    Flutter做的App怎么自动更新呢 首先要用到两个依赖一个叫update app 另外一个叫package info 还有一个叫Dio 一个是用来下载App的 一个是用来获取当前App的版本信息的 一个是用来网络链接的 flutter
  • axure能做剪切蒙版吗_Axure图片裁切功能

    平时做原型时经常会用到一张图片的某些部分 这时候我们一般都会借助于其他图片处理工具先处理好 再导入到原型中 其实Axure有简单的图片裁切功能 基本可以满足我们大部分的需求 下面介绍一下 使用axure7 1 图片裁割 通过该功能可以把图片
  • C++ 中 enable_shared_from_this 的使用总结

    背景 enable shared from this 是 C 11 定义在头文件 include 中的一个模板类 其作用是在类的内部安全的得到 this 指针的 shared ptr 版本 获取 this 的 shared ptr 版本 概