shared_from_this

1. 核心痛点:为什么要用它?

问题场景: 当我们需要在类的成员函数内部 获取当前对象的 shared_ptr(即"把我自己交给别人管理")时。

错误做法: 直接使用 this 指针创建 shared_ptr

复制代码
// ❌ 绝对禁止!
std::shared_ptr<T> sp(this);
  • 后果: 导致 Double Free(重复释放)
  • 原因: 这样会创建一个新的控制块 。导致两个独立的 shared_ptr 管理同一块内存,引用计数互不通气,最终分别析构时都会尝试 delete 对象。

正确做法: 使用 shared_from_this()

  • 作用: 它查找并返回已存在的控制块,确保引用计数正确增加,而不是新建控制块

2. 标准用法 (代码模板)

使用时需满足两个语法条件:

  1. 类必须公有继承 (public)std::enable_shared_from_this<T>

  2. 对象必须由 shared_ptr 管理。

    #include

    class Worker : public std::enable_shared_from_this { // 1. 继承
    public:
    void joinWorkGroup() {
    // 2. 获取自己的 shared_ptr
    std::shared_ptr self = shared_from_this();

    复制代码
     // 业务逻辑...

    }
    };

    int main() {
    // 3. 必须使用 shared_ptr 创建对象
    auto w = std::make_shared();
    w->joinWorkGroup();
    return 0;
    }


3. 底层原理 (面试考点)

enable_shared_from_this 是如何工作的?

  1. 内部成员: 该类内部隐藏了一个成员变量 mutable std::weak_ptr<T> weak_this;
  2. 延迟初始化:
    • 这个 weak_this不在构造函数中初始化。
    • 它是在外部第一次 创建 shared_ptr<T>(如 make_shared)时,由 shared_ptr 的构造函数检测并初始化的。
  1. 调用机制:
    • shared_from_this() 本质上就是执行 return weak_this.lock();
    • 它利用内部保存的弱引用,升级为一个新的强引用返回。

4. 三大"死亡陷阱" (易错点)

❌ 陷阱一:在构造函数中调用

  • 现象: 抛出 std::bad_weak_ptr 异常,程序崩溃。
  • 原因: 构造函数执行时,对象刚刚建立,外部的 shared_ptr 还没有机会初始化内部的 weak_this。此时 weak_ptr 是空的。
  • 解决: 使用"二段式构造"(先构造,再调用 init 函数),或者在其他成员函数中使用。

❌ 陷阱二:对象不是 shared_ptr 管理的

  • 场景: 对象在 上,或者通过 new 出来的裸指针

    Worker w;
    w.joinWorkGroup(); // 崩溃!

  • 原因: 没有外部 shared_ptr 介入,内部的 weak_this 永远不会被初始化,一直是空的。

❌ 陷阱三:私有继承 (Private Inheritance)

  • 场景: class Worker : std::enable_shared_from_this<Worker> (默认为 private)。
  • 原因: shared_ptr 的构造函数无法访问基类的成员,导致无法初始化 weak_this。必须显式写出 public

5. 一句话总结

shared_from_this****是为了解决"裸指针 this****变 shared_ptr****导致的多重释放"问题,其原理是利用内部隐藏的 weak_ptr****进行"借尸还魂"(共享控制块),但切记不可在构造函数中使用。

相关推荐
GIS阵地8 小时前
QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)
开发语言·前端·c++·qt·qgis
王维同学8 小时前
[原创][Windows C++]LSA 认证、安全与通知包的注册表枚举
c++·windows·安全
茯苓gao8 小时前
嵌入式开发笔记:EtherCAT协议从硬件到软件完整配置指南——从零搭建一套EtherCAT通信系统
笔记·嵌入式硬件·学习
whyTeaFo8 小时前
GAMES101: Lecture 9: Shading 3(Texture Mapping cont.) ppt笔记
笔记
_wyt0019 小时前
完全背包问题详解
c++·背包dp
chase。10 小时前
【学习笔记】PointWorld:迈向通用机器人操控的3D世界模型
笔记·学习·机器人
皓月斯语11 小时前
B3842 [GESP202306 三级] 春游 题解
数据结构·c++·算法·题解
萌动的小火苗12 小时前
嵌入式开发中的栈与队列:任务调度为什么依赖数据结构
数据结构·c++·单片机·嵌入式硬件
星恒随风12 小时前
C++ STL 栈详解:stack 的使用、经典题目与简单模拟实现
开发语言·数据结构·c++·笔记·学习
txzrxz12 小时前
单调队列讲解
数据结构·c++·算法·单调队列