C++ 中的 enable_shared_from_this 详解

C++11中enable_shared_from_this的用法解析 什么是 enable_shared_from_this? 下面摘自 cpp reference 中概述 C++11开始时支持 enable_shared_from_this,它一个模板类,定义在头文件 <memory>,其原型为: template< class T > class enable_shared_from_this; std::enable_shared_from_this 能让其一个对象(假设其名为 t ,且已被一个 std::shared_ptr 对象 pt 阅读详情

# C++ 中的 `enable_shared_from_this` 详解

`enable_shared_from_this` 是 C++ 标准库中的一个模板类,用于解决在类的成员函数中需要获取指向自身的 `shared_ptr` 的问题。

## 基本概念

当一个对象由 `shared_ptr` 管理时,如果你想在对象的成员函数中获得一个指向自身的 `shared_ptr`,直接使用 `this` 创建新的 `shared_ptr` 会导致多个不相关的 `shared_ptr` 管理同一个对象,从而造成重复释放的问题。

`enable_shared_from_this` 提供了安全的解决方案。

## 基本用法

```cpp
#include <memory>
#include <iostream>

class MyClass : public std::enable_shared_from_this<MyClass> {
public:
    std::shared_ptr<MyClass> getShared() {
        return shared_from_this();  // 安全地获取 shared_ptr
    }
    
    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    
    // 安全地获取 shared_ptr
    std::shared_ptr<MyClass> ptr2 = ptr1->getShared();
    
    std::cout << "ptr1 use_count: " << ptr1.use_count() << std::endl;  // 输出 2
    std::cout << "ptr2 use_count: " << ptr2.use_count() << std::endl;  // 输出 2
    
    ptr2->doSomething();
    
    return 0;
}
```

## 使用注意事项

1. **必须在对象已被 shared_ptr 管理时使用**:
   ```cpp
   // 错误用法 - 对象未被 shared_ptr 管理
   MyClass obj;
   auto ptr = obj.shared_from_this();  // 抛出 std::bad_weak_ptr 异常
   ```

2. **不能在构造函数中使用**:
   ```cpp
   class MyClass : public std::enable_shared_from_this<MyClass> {
   public:
       MyClass() {
           // 错误 - 此时对象还未被 shared_ptr 管理
           auto ptr = shared_from_this();  // 会抛出异常
       }
   };
   ```

3. **不能在析构函数中使用**:
   ```cpp
   class MyClass : public std::enable_shared_from_this<MyClass> {
   public:
       ~MyClass() {
           // 错误 - 此时 shared_ptr 引用计数可能已经为 0
           auto ptr = shared_from_this();  // 未定义行为
       }
   };
   ```

## 实际应用场景

1. **异步回调中保持对象存活**:
   ```cpp
   class NetworkService : public std::enable_shared_from_this<NetworkService> {
   public:
       void startAsyncOperation() {
           auto self = shared_from_this();
           asyncOperation([self]() {
               // 回调中 self 保持对象存活
               self->onOperationComplete();
           });
       }
       
       void onOperationComplete() {
           std::cout << "Operation completed" << std::endl;
       }
   };
   ```

2. **链式调用**:
   ```cpp
   class Builder : public std::enable_shared_from_this<Builder> {
   public:
       std::shared_ptr<Builder> step1() {
           // 执行步骤1
           return shared_from_this();
       }
       
       std::shared_ptr<Builder> step2() {
           // 执行步骤2
           return shared_from_this();
       }
   };
   
   // 使用
   auto builder = std::make_shared<Builder>();
   builder->step1()->step2();
   ```

## 实现原理

`enable_shared_from_this` 内部维护了一个 `weak_ptr`,当对象被 `shared_ptr` 管理时,`shared_ptr` 的构造函数会检测对象是否继承自 `enable_shared_from_this`,如果是,则初始化内部的 `weak_ptr`。

`shared_from_this()` 实际上是通过这个 `weak_ptr` 来创建一个新的 `shared_ptr`。

## 线程安全性

`shared_from_this()` 是线程安全的,但前提是对象的生命周期管理(即所有相关的 `shared_ptr` 操作)也是线程安全的。

## 替代方案

如果你不能或不想继承 `enable_shared_from_this`,可以考虑以下替代方案:

1. **传递 shared_ptr 作为参数**:
   ```cpp
   void MyClass::memberFunction(std::shared_ptr<MyClass> self) {
       // 使用 self
   }
   ```

2. **使用 weak_ptr 成员变量**:
   ```cpp
   class MyClass {
       std::weak_ptr<MyClass> weak_this;
   public:
       void setSelf(const std::shared_ptr<MyClass>& self) {
           weak_this = self;
       }
       
       std::shared_ptr<MyClass> getShared() {
           return weak_this.lock();
       }
   };
   ```

`enable_shared_from_this` 是一个强大的工具,但需要正确使用以避免潜在的问题。

C++智能指针的enable_shared_from_this和shared_from_this机制 知识的学习在于点滴记录,坚持不懈;知识的学习要有深度和广度,不能只流于表面,坐井观天;知识要善于总结,不仅能够理解,更知道如何表达! 目录问题代码代码清单1代码清单2shared_ptr原理分析 如果不熟悉C++带引用计数的智能指针shared_ptr和weak_ptr,请参考我的另一篇介绍智能指针的博客:https://blog.youkuaiyun.com/QIANGWEIYUAN/article/d... 阅读详情

相关推荐

C++ std::enable_shared_from_this 类模板到底有什么用?【 C++11 标准中正式引入】

本文介绍了C++中std::enable_shared_from_this模板的用法,通过HttpServer示例说明其重要性。在异步回调中直接使用this指针可能导致对象提前销毁引发未定义行为,而shared_from_this()通过共享所有权确保对象生命周期延长到异步操作完成。文章分析了其工作原理:shared_from_this()会创建新的shared_ptr副本,增加引用计数,直到回调执行完毕才可能释放对象。该模板是解决异步操作中对象生命周期问题的标准工具,能有效防止悬空指针问题。

qq_35814377的博客 2335

enable_shared_from_this

shared_from_this()不能在构造函数里调用,因为在构造对象的时候,它还没有被交给shared_ptr接管。它提供了一种机制,使类能够安全地从成员函数内部获得指向自身的。是一个基类模板,用于解决在类成员函数中获取类对象的。下面是一个示例代码,展示了。

hanhan的博客 2271

C++(11):enable_shared_from_this

可见通过shared_ptr(this)这种方式虽然返回了一个shared_ptr对象,但是这里有一个问题。shared_ptr(this)这种方式相当于通过this重新构造了一个shared_ptr,也就是说也重新生成了一个管理对象。如果一个类的对象被shared_ptr管理着,然后该类的某个成员函数需要返回一个指向该对象本身的shared_ptr,该怎么实现呢?可以了解到,智能指针是通过一个管理对象管理着对象的计数,当多个智能指针引用到同一个对象时,是通过其管理对象来进行维护的。......

风静如云的博客 606

enable_shared_from_this使用介绍

智能指针之enable_shared_from_this

Erice_s的博客 3916

C++ enable_shared_from_this使用详解

enable_shared_from_this 是 C++ 标准库中提供的一个辅助类模板,主要用于支持对象从成员函数中安全地获得一个 shared_ptr 指向它自己。它的作用是允许对象在其成员函数内部生成指向它本身的 shared_ptr,从而确保对象在生命周期管理中的正确性,特别是在对象存在于多个地方并且需要共享所有权时。

琅嬛福地 648

海康摄像头RTSP流延迟优化实战:从VLC到OpenCV的5种方案对比与性能调优

本文针对海康摄像头RTSP流的高延迟问题,深入剖析了延迟根源,并系统对比了从VLC、OpenCV到海康官方SDK、FFmpeg及硬件加速等五种主流方案的性能表现。重点分享了缓冲区设置、协议优化、多线程架构与硬件解码等实战调优技巧,旨在帮助开发者将视频流延迟从秒级优化至毫秒级,满足工业检测、安防监控等高实时性场景需求。

hh234的博客 806

深入解析C++ this指针:从内存模型到多线程实战

在C++面向对象编程中,成员函数如何访问对象的数据?其核心机制在于一个隐式传递的`this`指针。从编译器视角看,`this`实质上是成员函数的第一个参数,类型为`ClassName* const`,它指向当前对象实例的内存起始地址,使得函数内部能够定位并操作对象的成员变量。这一机制不仅是实现封装的基础,更是理解C++对象模型、虚函数表(vtable)及多态行为的关键。在工程实践中,正确使用`this`指针对于实现链式调用、解决命名冲突至关重要,尤其在涉及Lambda表达式捕获和异步编程时,必须警惕悬垂指针

chulilang8944的博客 391

人类肠道微生物群落代谢建模

MICOMWeb 是款用户友好型网站,专为人类肠道微生物群落代谢建模设计。该网站旨在解决基因组尺度代谢模型(in silico)构建过程中的3大限制:① 使用 MICOM Python 包进行通量平衡分析时对用户 Python 编程知识的要求;② 支持预定义和用户自定义饮食,以生成专属代谢模型;③ 处理宏基因组鸟枪法测序或 16S 扩增子测序获得的真实丰度数据时,所需的高通量计算基础设施。本文展示了 MICOMWeb 的核心功能,用户可轻松开展虚拟实验,为3个已发表数据集的实验验证生成功能性假设。

多组・学・多组学 1169

深入理解C++ this指针:从内存模型到现代编程实践

在C++面向对象编程中,this指针是一个核心概念,它作为指向当前对象实例的隐式参数,是理解对象模型和成员函数调用的关键。从编译器视角看,this指针在成员函数调用时被自动传递,决定了函数如何访问对象的成员数据。这一机制不仅支撑了链式调用、对象间交互等基础功能,更是实现多态、虚函数等高级特性的底层基础。在智能指针、异步回调等现代C++实践中,正确管理this指针的生命周期至关重要,例如使用std::enable_shared_from_this避免悬垂指针,或在Lambda表达式中通过弱引用确保线程安全。掌

weixin_33805743的博客 356

深入剖析一个卷积块(ConvBlock)

深入剖析一个卷积块(ConvBlock)

qq_45670407的博客 1925

【车辆仿真】从0开始建立dSPACE RT Simulink工程:输出模拟电平

0基础建议先看下前面的博文,补充基础知识。原来的博文太长太复杂,后续我会逐步梳理改进,去除操作层面的内容,仅关注知识层面,提升系列博文的系统性。【工程环境信息】:上位机:惠普台式PC(Windows 11专业版)下位机(实时机):SCALEXIO RTPC板卡:DS2680。

winnizap的博客 2055

C++ weak_ptr详解:解决循环引用与实现安全缓存的智能指针

在C++内存管理中,智能指针通过自动管理对象生命周期,显著提升了资源管理的安全性与便利性。其核心原理基于引用计数技术,当对象的引用计数归零时自动释放内存,从而避免内存泄漏。这一机制在构建复杂软件系统时具有重要技术价值,尤其在处理对象间关联关系、实现资源缓存等场景中。然而,当对象间存在相互引用时,传统的强引用智能指针会导致循环引用问题,使得引用计数无法归零,造成内存泄漏。为此,C++标准库引入了weak_ptr这一弱引用智能指针,它允许观察一个由shared_ptr管理的对象而不增加其引用计数,从而打破循环引

weixin_33393017的博客 356

【前端】【面试】【业务场景】前端如何获取并生成设备唯一标识

问题:前端如何获取并生成设备唯一标识?核心要点:浏览器原生信息有限,但通过组合多个维度可生成设备指纹(Device Fingerprint),用于唯一标识设备。常见方式浏览器信息(User-Agent)屏幕与系统参数本地存储标识(localStorage / cookie)第三方指纹库(如 FingerprintJS)方式优点缺点手动组合指纹实现简单不稳定,识别率低持久化强容易被用户清除识别率高、稳定性好依赖第三方库IP 地址识别网络识别粗略共享网络环境下重复可能大。

qq_59344127的博客 1794

C++智能指针循环引用破解

智能指针在管理动态内存时可能遇到循环引用问题,导致内存泄漏。weak_ptr是打破循环引用的关键工具,它不增加引用计数。循环引用发生在两个对象互相持有shared_ptr。C++智能指针循环引用破解。

2501_94114815的博客 148

腾讯滑块验证码collect参数逆向与JSVMP对抗实战

本文深入解析腾讯滑块验证码collect参数的逆向过程与JSVMP虚拟机对抗技术。通过详细的环境搭建、抓包分析和JSVMP逆向技巧,揭示collect参数的生成逻辑与加密流程,并提供完整的模拟实现方案和常见问题排查方法,助力开发者突破腾讯天御验证码的防护机制。

weixin_29009501的博客 1573

Android PMS——概述(一)

PMS(Package Manager Service)是 Android 操作系统的一个重要组件,它负责管理应用程序的包信息以及与应用程序的安装、卸载、权限控制等相关功能,确保应用程序的安全性和稳定性。 Android PMS 负责维护一个应用程序包的清单信息,该清单是一个 XML 文件,包含应用程序的各种元数据,例如应用程序的包名、版本号、权限要求、组件信息等。PMS通过访问该清单文件来获取应用程序的信息。 此外,Android PMS 还负责应用程序的安装和卸载。在安装应用

小旭的专栏 1667

enable_shared_from_this 机制

shared_ptr会增加资源的引用计数,常用于管理对象的生命周期。weak_ptr不会增加资源的引用计数,常作为观察者用来判断对象是否存活。使用shared_ptr的普通拷贝构造函数会产生额外的引用计数对象,可能导致对象多次析构。使用shared_ptr的拷贝构造函数则只影响同一资源的同一引用计数的增减。当需要返回指向当前对象的shared_ptr时,优先使用enable_shared_from_this机制。httpshttpshttps。......

weixin_44614002的博客 3339

把注释掉的代码删除掉:在 SAP ABAP 团队里打造可回溯、可测试、可演进的代码库

摘要 SAP ABAP项目中常见的"注释掉代码"反模式存在严重隐患:它增加代码噪音,制造虚假安全感,并可能引发安全和合规风险。Clean ABAP指南明确建议删除这类代码,理由包括: 版本控制系统已提供完整历史回溯能力 注释代码会误导开发者,增加理解成本 临时禁用需求应通过Feature Toggle实现 必须保留的参考代码应放入$TMP等隔离区域 团队应建立自动化检查机制,将"删除注释代码"纳入工程规范,确保代码库只表达当前有效的行为逻辑。在AI时代,可以利用工具辅

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2450

【转载】C++11中enable_shared_from_this的用法解析

C++11 开始支持 enable_shared_from_this,它是一个模板类,定义在头文件 ,其原型为:std::enable_shared_from_this 能让其一个对象(假设其名为 t ,且已被一个 std::shared_ptr 对象 pt 管理)安全地生成其他额外的 std::shared_ptr 实例(假设名为 pt1, pt2, … ),它们与 pt 共享对象 t 的所有权。

好好学习,天天向上~ 536

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C++11 shared_from_this学习

最近学习网络变成发现一些C++源码库中封装对象时会公有继承enable_shared_from_this; 用一个案例进行说明,案例代码如下: #include <iostream> #include <memory> #include <stdio.h> using namespace std; class C : public enable_shared_from_this<C> { public: shared_ptr&

向往天空的鱼 579

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C++11中模板类std::enable_shared_from_this的使用

C++11中的模板类template <class T> class enable_shared_from_this功能:允许从std::enable_shared_from_this派生的类T的对象创建指向自身的shared_ptr实例并与现有的shared_ptr对象共享所有权。T需要为完整类型,通常是final的。如果使用this创建一个新的shared_ptr,则其与现有的shared_ptr所有者不同,从而会导致无效引用或导致此对象被删除多次。 std::...

网络资源是无限的 1745

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C++ 静态多态实现方式

通过`std::enable_if`或C++20的`requires`约束模板实例化条件,可以在编译期筛选有效重载。两者结合能实现类似动态多态的接口统一性,同时保持零成本抽象的优势。C++还提供了一种更高效的实现方式——静态多态,它通过编译期决议避免了运行时开销。这种编译期表达式树重构,是静态多态在数值计算领域的典型应用,兼具抽象性与运行时性能。静态多态通过编译期生成代码,在性能敏感的系统中展现出不可替代的价值。从模板元编程到现代C++的概念约束,其实现方式不断进化,为开发者提供了更多零开销抽象的可能性。

bypzqn_354的博客 45
上一篇: 深入分析linux内核源代码
下一篇: C++ 中的 enable_shared_from_this 详解
SimpleForest
博客等级 码龄10年 171粉丝 95原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值