现代C++:使用 shared_from_this 防止 this 提前被释放

news2024/10/7 16:17:27

首先概括一下shared_from_this的作用:可以在类的成员函数中直接通过this得到指向当前所在对象的shared_ptr的智能指针,具体操作如下。

使用方法

设需要提供shared_from_this方法的类为C0定义为类,首先需要将C0定义为 std::enable_shared_from_this<C0>的派生类,然后C0就继承了shared_from_this这个方法,示例如下:

class C0 : public std::enable_shared_from_this<C0> {
public:
    shared_ptr<C0> get_shared() {
        return shared_from_this();
    }
};

示例中类C0的对象中可以通过get_shared返回一个指向当前对象的智能指针,测试如下:

int main() {
    shared_ptr<C0> tp1 = make_shared<C0>(), p1 = tp1->get_shared();
    assert(p1.use_count() == 2);
}

防止 this 提前被释放

直接看一个例子:

class C1 {
public:
    int *val = new int(1);

    void test() {
        auto x = thread([this]() {
            sleep(1);
            if (this->val)
                cout << "in thread, *this->val: " << *this->val << endl;
            else
                cout << "in thread, this->val is null" << endl;
        });
        x.detach();//主线程不等待x线程结束
    }

    ~C1() {
        delete val;
        val = nullptr;
        cout << "~C1()" << endl;
    }
};

int main() {
    {
        shared_ptr<C1> obj = make_shared<C1>();
        obj->test();
    }//obj生命周期结束
    sleep(2);
}

运行结果如下:

在这里插入图片描述

在创建的子线程x中暂停1秒后,主线程已从test()返回,之后obj生命周期结束,obj指向的对象被释放,所以子线程x执行的匿名函数捕获的this已经被释放。

再看一个使用shared_from_this防止this被释放的例子:

class C2 : public std::enable_shared_from_this<C2> {
public:
    int *val = new int(1);

    void test() {
        auto x = thread([self = shared_from_this()]() {
            sleep(1);
            if (self->val)
                cout << "in thread, *self->val: " << *self->val << endl;
            else
                cout << "in thread, self->val is null" << endl;
        });
        x.detach();
    }

    ~C2() {
        delete val;
        val = nullptr;
        cout << "~C2()" << endl;
    }
};

int main() {
    {
        shared_ptr<C2> obj = make_shared<C2>();
        obj->test();
    }
    sleep(2);
}

运行结果如下:

在这里插入图片描述

与之前不同的是,子线程x执行的匿名函数捕获列表中定义了一个指向this的智能指针self,这样即使主线程中的智能指针obj生命周期结束,obj指向的对象也不会释放,从子线程的角度来看就避免了 this 提前被释放的问题。


参考:
https://stackoverflow.com/questions/712279/what-is-the-usefulness-of-enable-shared-from-this
https://en.cppreference.com/w/cpp/language/lambda

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/886630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NCAA棒球介绍·棒球1号位

NCAA棒球介绍 1. NCAA简介 NCAA&#xff08;National Collegiate Athletic Association&#xff09;的历史与发展 NCAA&#xff0c;这个拥有94年悠久历史的体育联盟&#xff0c;从一所校际体育比赛&#xff0c;发展成为世界上最大的大学体育组织&#xff0c;NCAA的发展历程充…

.NET Core发布到IIS

项目介绍 1、开发工具Visual Studio 2017&#xff0c;语言C#&#xff0c;SQL SERVER&#xff0c;WIN10 2、本地IIS&#xff0c;手机上或其他用户在和本地在同一个局域网内访问,同时要把防火墙关掉 3、IIS全名Internet Information Services&#xff0c;用来发布网站 先决条件 安…

[UE4][C++]使用qrencode动态生成二维码

一、使用CMake编译x64版本qrencode 下载地址 GitHub - fukuchi/libqrencode: A fast and compact QR Code encoding libraryA fast and compact QR Code encoding library. Contribute to fukuchi/libqrencode development by creating an account on GitHub.https://github.…

同创永益郑阳|与数智化共舞·业务稳定性保障新动力

2023年8月2日&#xff0c;由北大创新评论主办的2023 Inno China中国产业创新大会-保险产业创新论坛在京举办。本次论坛由同创永益、青牛软件、DaoCloud道客联合主办&#xff0c;INNO创新家、产业集群发展提供战略支持&#xff0c;未名数创承办&#xff0c;邀请到了学术专家、行…

抖音怎样发才有更多人看?四川玖璨电商

抖音是一款非常受欢迎的短视频应用程序&#xff0c;如果你想让更多人看到你的视频&#xff0c;那么你需要学习如何正确地使用抖音平台。在本文中&#xff0c;我们将提供一些有用的建议&#xff0c;以帮助你增加你的观众数量&#xff0c;让你的视频更加受欢迎。 1. 精心选择主题…

配置/var/tmp/fstab 权限/配置用户账户/查找文件/查找字符串

目录 配置/var/tmp/fstab 权限 配置用户账户 查找文件 查找字符串 创建归档 配置/var/tmp/fstab 权限 配置文件权限&#xff0c;将文件 /etc/fstab 复制到 /var/tmp/fstab 。配置 /var/tmp/fstab 的权限以满足 如下条 件&#xff1a; /var/tmp/fstab 属于 root 用户…

光致发光荧光量子产率测试系统

荧光量子产率&#xff0c;是单位时间&#xff08;s&#xff09;内&#xff0c;发射荧光的光子数与吸收激发光的光子数之间的比值&#xff0c;符号φf。它表示物质将吸收的光能转变成荧光的能力&#xff0c;是荧光物质一个最基本而重要的参数。φf值的大小与物质的化学结构紧密相…

ARM64是什么意思?与x86有什么区别?

你知道ARM64是什么意思&#xff1f;与x86有什么区别&#xff1f;哪款堡垒机支持ARM64架构&#xff1f;且听我道来。 ARM64是什么意思&#xff1f; 【回答】&#xff1a;ARM64是CPU构架的一种&#xff0c;通常用于手机、平板等CPU&#xff0c;目前笔记本电脑也会采用ARM64构架…

SpringBoot案例 调用第三方接口传输数据

一、前言 最近再写调用三方接口传输数据的项目&#xff0c;这篇博客记录项目完成的过程&#xff0c;方便后续再碰到类似的项目可以快速上手 项目结构&#xff1a; 二、编码 这里主要介绍HttpClient发送POST请求工具类和定时器的使用&#xff0c;mvc三层架构编码不做探究 pom.x…

磁力线试验+多图

今天要磨制一个钢针工具。磨下来很多的铁屑&#xff0c;灵机一动&#xff0c;何不来试验一下磁铁的磁力线。这可是难得的材料。 下放7颗强力磁铁&#xff0c;可见强力磁铁的磁力线非常集中。 下放直径4CM的喇叭磁铁 强力磁铁U型铁 强力磁铁E型铁氧体磁芯&#xff0c;可见磁力线…

项目管理工具和方法有哪些:了解项目管理的必备工具和有效方法

先谈谈什么是项目管理&#xff0c;简单直白&#xff0c;就是对项目进行管理。项目管理涉及有效的计划和对工作的系统管理&#xff0c;但很多工具可以使项目管理更有效、更高效。比如&#xff0c;Zoho Projects项目管理工具。 1.项目合理拆解 当确定了项目目标后&#xff0c;无疑…

夏季用电高峰,智慧路灯杆如何助力节能减排

近年来&#xff0c;气温对用电的影响越发突出&#xff0c;持续高温拉动用电负荷快速增加&#xff0c;导致部分地区的电力供需偏紧形势进一步加剧。据媒体报道&#xff0c;今年夏季电力供需形势仍旧紧张&#xff0c;包括安徽、四川、重庆、广东等多地发出节电倡议&#xff0c;包…

驱动 实现三个灯的亮灭

1、编写LED灯的驱动&#xff0c;可以控制三个灯&#xff0c;应用程序中编写控制灯的逻辑&#xff0c;要使用自动创建设备节点机制 head.h #ifndef __HEAD_H__ #define __HEAD_H__#define PHY_LED1_MODER 0x50006000 #define PHY_LED1_ODR 0x50006014 #define PHY_LED1_RCC 0x…

解决git reset --soft HEAD^撤销commit时报错

今天在使用git回退功能的时候&#xff0c;遇到以下错误&#xff1a; 解决git reset --soft HEAD^撤销commit时报错 问题&#xff1a; 在进行完commit后&#xff0c;想要撤销该commit&#xff0c;于是使用了git reset --soft HEAD^命令&#xff0c;但是出现如下报错&#xff1…

Java 的文档注释其实并没有那么简单

Java 的文档注释其实并没有那么简单 我们在写java 程序的只有三种注释方式&#xff1a; “//” 后面跟上想要写入的注释 “/* */” 里面跟上想要写入的注释 “/** */” 说明注释&#xff0c;可以多行之间注释 说明注释允许我们在程序中嵌入关于程序的信息。 我们可以使用…

节点不连续伽辽金方法在求解线性和非线性平流方程中的一维实现(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

嵌入式:ARM Day4

一、自己编写代码实现三盏灯点亮 源码&#xff1a; .text .global _start _start: 进行一次初始化bl RCC_INITbl LED1_INITbl LED2_INITbl LED3_INITb looploop: 循环开关灯bl LED1_ONbl delay_1sbl LED1_OFFbl delay_1sbl LED2_ONbl delay_1sbl LED2_OFFbl delay_1sbl…

13 Web全栈 pnpm

什么是pnpm&#xff1f; 可以理解成performant npm缩写 速度快、节省磁盘空间的软件包管理器 特点 快速- pnpm比其他包管理器快2倍高效- node_modules中的文件链接自特定的内容寻址存储库支持monorepos- 内置支持单仓多包严格- pnpm默认创建了一个非平铺的node_modules 因此代…

Spring中循环依赖解决方案

循环依赖 循环依赖是Spring框架中常见的问题之一&#xff0c;当两个或多个类相互引用对方时&#xff0c;就会出现循环依赖的情况。这种情况下&#xff0c;Spring框架无法确定哪个类应该先实例化和初始化&#xff0c;从而导致异常。常见的解决方法有&#xff1a;构造函数注入、s…

STM32单片机通过串口烧录hex程序

我之前买过一个STM32最小程序单片机&#xff0c;原来下载51单片机都是使用串口方式&#xff0c;这里也通过串口方式烧录STM32单片机&#xff0c;还需要借助一个USB TO TTL工具。 USB TO TTL工具类似一个U盘工具&#xff0c;只不过它另一端是接线&#xff0c;一般电脑会自动安装…