C++11新特性之十:enable_shared_from_this

2023-05-16

       enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为:

template< class T > class enable_shared_from_this;
       std::enable_shared_from_this 能让一个对象(假设其名为 t ,且已被一个 std::shared_ptr 对象 pt 管理)安全地生成其他额外的 std::shared_ptr 实例(假设名为 pt1, pt2, ... ) ,它们与 pt 共享对象 t 的所有权。
       若一个类 T 继承 std::enable_shared_from_this<T> ,则会为该类 T 提供成员函数: shared_from_this 。 当 T 类型对象 t 被一个为名为 pt 的 std::shared_ptr<T> 类对象管理时,调用 T::shared_from_this 成员函数,将会返回一个新的 std::shared_ptr<T> 对象,它与 pt 共享 t 的所有权。

一.使用场合

       当类A被share_ptr管理,且在类A的成员函数里需要把当前类对象作为参数传给其他函数时,就需要传递一个指向自身的share_ptr。

1.为何不直接传递this指针

       使用智能指针的初衷就是为了方便资源管理,如果在某些地方使用智能指针,某些地方使用原始指针,很容易破坏智能指针的语义,从而产生各种错误。

2.可以直接传递share_ptr<this>么?

       答案是不能,因为这样会造成2个非共享的share_ptr指向同一个对象,未增加引用计数导对象被析构两次。例如:

#include <memory>
#include <iostream>

class Bad
{
public:
	std::shared_ptr<Bad> getptr() {
		return std::shared_ptr<Bad>(this);
	}
	~Bad() { std::cout << "Bad::~Bad() called" << std::endl; }
};

int main()
{
	// 错误的示例,每个shared_ptr都认为自己是对象仅有的所有者
	std::shared_ptr<Bad> bp1(new Bad());
	std::shared_ptr<Bad> bp2 = bp1->getptr();
	// 打印bp1和bp2的引用计数
	std::cout << "bp1.use_count() = " << bp1.use_count() << std::endl;
	std::cout << "bp2.use_count() = " << bp2.use_count() << std::endl;
}  // Bad 对象将会被删除两次
输出结果如下:


当然,一个对象被删除两次会导致崩溃。


正确的实现如下:

#include <memory>
#include <iostream>

struct Good : std::enable_shared_from_this<Good> // 注意:继承
{
public:
	std::shared_ptr<Good> getptr() {
		return shared_from_this();
	}
	~Good() { std::cout << "Good::~Good() called" << std::endl; }
};

int main()
{
	// 大括号用于限制作用域,这样智能指针就能在system("pause")之前析构
	{
		std::shared_ptr<Good> gp1(new Good());
		std::shared_ptr<Good> gp2 = gp1->getptr();
		// 打印gp1和gp2的引用计数
		std::cout << "gp1.use_count() = " << gp1.use_count() << std::endl;
		std::cout << "gp2.use_count() = " << gp2.use_count() << std::endl;
	}
	system("pause");
} 
输出结果如下:

二.为何会出现这种使用场合

       因为在异步调用中,存在一个保活机制,异步函数执行的时间点我们是无法确定的,然而异步函数可能会使用到异步调用之前就存在的变量。为了保证该变量在异步函数执期间一直有效,我们可以传递一个指向自身的share_ptr给异步函数,这样在异步函数执行期间share_ptr所管理的对象就不会析构,所使用的变量也会一直有效了(保活)。

具体的应用可以参考:Boost.Asio C++ 网络编程之五:TCP回显服务端/客户端

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

C++11新特性之十:enable_shared_from_this 的相关文章

随机推荐

  • 【Python学习教程】Python流程控制

    文章目录 Python if else条件语句详解if else 如何判断表达式是否成立 Python if else对缩进的要求不要忘记缩进缩进多少合适 xff1f 所有语句都要缩进同一代码块缩进量要相同不要随便缩进 Python if语
  • 【Python学习教程】Python函数和lambda表达式

    文章目录 Python函数 xff08 函数定义 函数调用 xff09 用法详解Python函数的定义Python函数的调用为函数提供说明文档 Python函数值传递和引用传递 xff08 包括形式参数和实际参数的区别 xff09 Pyth
  • 【Python学习教程】Python类和对象

    文章目录 什么是面向对象 xff0c Python面向对象 xff08 一切皆对象 xff09 面向对象相关术语 Python class xff1a 定义类 xff08 入门必读 xff09 Python类的定义 Python init
  • 最易学和最难学的编程语言Top 5

    文 白开水不加糖 出品 OSC开源社区 xff08 ID xff1a oschina2013 xff09 在线学习平台 Springboard 罗列了一个最容易学习和最难学的编程语言 Top 5 榜单 事实上 xff0c 问一个程序员最容易
  • 【Python学习教程】Python异常处理机制

    文章目录 什么是异常处理 xff0c Python常见异常类型 xff08 入门必读 xff09 Python语法错误Python运行时错误 Python异常处理机制到底有什么用 xff1f Python try except异常处理详解
  • 【NumPy教程】(快速入门版)

    文章目录 读者阅读条件 NumPy是什么NumPy使用需求NumPy应用场景 NumPy下载与安装Windows系统安装MacOSX系统安装Linux系统安装1 Ubuntu Debian2 Redhat CentOS NumPy ndar
  • Pillow(PIL)入门教程(非常详细)

    文章目录 相关资源 教程特点读者 amp 阅读条件 Pillow是什么Pillow版本支持Pillow库特点1 支持广泛的文件格式2 提供了丰富的功能3 配合GUI工具使用 Pillow的下载与安装pip包管理器安装二进制包安装Anacon
  • Tkinter教程

    文章目录 Tkinter教程 xff08 非常详细 xff09 教程特点阅读条件 GUI是什么GUI发展史GUI应用领域GUI的优势GUI开发工具 Tkinter是什么第一个Tkinter程序1 主窗口设置2 添加文本3 添加按钮4 独立运
  • 成功解决卡巴斯基6莫名其妙自动关闭的问题

    卡巴斯基6确实是个不错的杀毒工具 xff0c 但是安装好后 xff0c 会有个特别烦人的问题 xff0c 老是会提示错误 xff0c 然后自动关闭 xff0c 在网上查了一下 xff0c 终于找到了解决方案 解决步骤如下 xff1a 1 进
  • Tcl和Tk教程

    在Python Tkinter中 xff0c 重新了解到TCL和Tk 想起之前在做分子动力学模拟的时候 xff0c 有用到一个软件 xff0c 其命令行好像就是支持Tcl脚本 xff0c 当时对CS没那么了解 xff0c 所以也就没有深入了
  • Gromacs安装教程及一些思考

    写这篇博客目的当然不是只安装一下GROMAC xff0c 而是想借这个机会思考一下认知的问题 想起来刚上研究生的时候 xff0c 要在Linux服务器上安装这个软件 xff0c 当时费了好大劲 xff0c 各种求助师兄 xff0c 虽然安装
  • 如何高效地学习开源项目

    转载于 xff1a https time geekbang org column article 10022 你好 xff0c 我是华仔 今天这期 特别放送 xff0c 我想和你聊聊如何高效地学习开源项目 xff0c 一方面澄清开源项目学习
  • 52个数据可视化图表鉴赏

    文章目录 1 弧线图2 面积图3 箭头图4 条形图5 布林线指标6 箱线图7 气泡地图8 子弹图9 凹凸图10 日历图11 烛台图12 卡通图13 弦图14 分级统计图15 组合图表16 连接地图17 控制图18 南丁格尔玫瑰图19 交叉表
  • 【程序员学理财】不同产业的市场规模

    程序员学理财 不同产业的市场规模 先来了解一些常识 三大产业 第一产业主要指生产食材以及其它一些生物材料的产业 xff0c 包括种植业 林业 畜牧业 水产养殖业等直接以自然物为生产对象的产业 xff08 泛指农业 xff09 第二产业主要指
  • 【程序员学理财】有哪些普通人应该知道的经济学常识?

    文章目录 一 前言二 宏观经济学1 名词定义2 主要内容 三 微观经济学1 名词定义2 研究内容3 对比区别 四 降息降准是什么意思 xff1f 五 一些常用术语1 沉没成本2 边际成本 一 前言 每天我们都在跟 经济 打交道 xff0c
  • 【程序员学理财】汽车行业、手机行业简单了解

    汽车行业 本文章不是专业的解读 xff0c 只是为了让自己对汽车行业建立一个大体的认知 先简单看两个新闻 xff1a 2021年销量出炉 xff0c 中国车企卷翻了 才一年 xff0c 智能车就不再是新势力专利 xff01 当然上面这些是从
  • 【LeetCode刷题日记】1996. 游戏中弱角色的数量

    题目 你正在参加一个多角色游戏 xff0c 每个角色都有两个主要属性 xff1a 攻击 和 防御 给你一个二维整数数组 properties xff0c 其中 properties i 61 attacki defensei 表示游戏中第
  • LEETCODE 编程训练

    转载于 xff1a https coolshell cn articles 12052 html Leetcode这个网站上的题都是一些经典的公司用来面试应聘者的面试题 xff0c 很多人通过刷这些题来应聘一些喜欢面试算法的公司 xff0c
  • 【程序员学理财】零和博弈和对股市的一些了解

    一 零和博弈 零和博弈 xff08 zero sum game xff09 xff0c 又称零和游戏 xff0c 与非零和博弈相对 xff0c 是博弈论的一个概念 xff0c 属非合作博弈 它是指参与博弈的各方 xff0c 在严格竞争下 x
  • C++11新特性之十:enable_shared_from_this

    enable shared from this是一个模板类 xff0c 定义于头文件 lt memory gt xff0c 其原型为 xff1a template lt class T gt class enable shared from