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

World Action Model:经典论文

郑困时,图prorpt为机量人压务时,退过驱制解弱词表(constrsinsd decoding), 强附模型只从.256个者动作token中保H, B象总注活地。始VLA之一,RT-2使用了大量的五联网VQ据与少里的机械网的AcSonDat行CoFine-Tunng, 独组sl, 共i744个episode,Mous使用三个专累模,分是vidogonmedel,actonesget,understandng。包的核定之的的观到沟血黄动作,预之后现(vorlemodel),tseing,2。

u013250861的博客 406

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

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

chulilang8944的博客 391

手把手教你用内核远程call实现64位进程注入(附完整ShellCode示例)

本文深入探讨了在Windows 64位环境下,通过内核态直接操作线程TrapFrame结构实现进程注入的高级技术。文章提供了从驱动框架设计、用户态-内核态通信,到定位修改TrapFrame、编写Shellcode及执行环境恢复的完整实战指南,并附有详细的代码示例,为安全研究人员和开发者提供了绕过用户态检测、实现底层远程代码执行的新思路。

weixin_28396629的博客 345

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

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

weixin_33805743的博客 356

Spark数据倾斜问题+解决方案

1、数据倾斜 数据倾斜指的是,并行处理的数据集中,某一部分(如Spark或Kafka的一个Partition)的数据显著多于 其它部分,从而使得该部分的处理速度成为整个数据集处理的瓶颈 数据倾斜俩大直接致命后果 1)数据倾斜直接会导致一种情况:Out Of Memory 2)运行速度慢 主要是发生在Shuffle阶段。同样Key的数据条数太多了。导致了某个key(下图中的80亿条)所在的Task数 据量太大了。远远超过其他Task所处理的数据量 一个经验结论是:一般情况下,OOM的原因都是数据倾斜 2、如

诸葛搏毅 6768

nmap、X-Scan漏洞扫描和Metasploit中用永恒之蓝漏洞入侵靶机并上传冰河

利用nmap、X-Scan扫描靶机的漏洞,在Metasploit中用扫描出的永恒之蓝漏洞入侵靶机,建立连接后上传冰河木马控制靶机,最后用冰河陷阱清除靶机的冰河木马,记一次完整的入侵控制实验。

m0_59302403的博客 4407

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

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

weixin_33393017的博客 356

实用电路精讲系列---快速精密桥式放大器电路

快速精密桥式放大器通过惠斯通电桥转换物理量为差分信号,经仪表放大器精密放大,具有高共模抑制、低噪声和宽带宽特性。其核心包含:电桥传感器转换、仪表放大器信号调理(增益可调、温漂补偿)、输出级适配ADC。典型应用包括智能断路器监测、胎压检测、电池安全预警等10大领域,需注意传感器-放大器-ADC最短路径布局。实用电路采用LT1057S和LT1010构建,实现稳定供电、差分处理、功率放大和桥式驱动,满足高精度、快速响应需求。该技术在工业控制、医疗设备等领域具有重要价值。

weixin_40590799的博客 1414

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

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

2501_94114815的博客 148

使用VScode编译AMI代码

我现在了解到的和拿到的code,都是基于AMI的code,一般的编译AMI都需要搭配使用AMI的编译环境Veb,而Veb用到现在,一直都觉得有点卡顿,浏览代码的体验也比VScode差很多。在这之前还要,考虑设置TOOLS_DIR和EWKE_DIR的环境变量,因为在Veb中是可以通过设置自动设置的,但是VScode里面没用设置环境变量的选项。这里可以看出,Veb工具栏中的Build和Rebuild All的命令对应这里的make和make rebuild,也就是说Veb是调用此命令进行编译的。

Dodijd的博客 1881

激光雷达点云配准:ICP与NDT算法详解

激光雷达点云配准:ICP与NDT算法详解​ ,人工智能,计算机视觉,大模型,AI,本文深入解析激光雷达点云配准的ICP与NDT算法。阐述了点云配准基础概念与评价指标,详解ICP算法原理、流程、最优变换矩阵计算、优缺点及改进版,给出Python代码示例;同样解析NDT算法的原理、流程、模型构建、优缺点、参数选择与代码示例。还对比两者在精度、效率、鲁棒性和适用场景的差异,提供算法选择建议,介绍实际应用案例、常见问题及解决方法,探讨算法发展趋势。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 15万+

enable_shared_from_this 机制

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

weixin_44614002的博客 3339

YOLOv8深度集成SDFM:显著增强特征细节与多尺度融合,实现小目标检测革命性提升

本文介绍了如何将SDFM(Superficial Detail Fusion Module)模块集成到YOLOv8目标检测模型中,以提升特征融合效能。SDFM通过精细的特征预校准、通道注意力机制和动态加权融合策略,有效解决了多尺度特征融合中的细节保留问题。实验表明,集成SDFM后YOLOv8的mAP50-95提升12.7%,召回率提升9.0%,精确率提升5.9%,显著增强了模型性能。教程详细阐述了SDFM的工作原理、代码实现步骤及优化思路,为研究者和开发者提供了实用的技术指南。

FJN110的博客 117

【转载】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

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

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

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

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

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

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、付费专栏及课程。

余额充值