当前位置: 首页 > news >正文

手写智能指针:带你彻底搞懂 C++ 内存管理的底层逻辑

博主介绍:程序喵大人

  • 35 - 资深C/C++/Rust/Android/iOS客户端开发
  • 10年大厂工作经验
  • 嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手
  • 《C++20高级编程》《C++23高级编程》等多本书籍著译者
  • 更多原创精品文章,首发gzh,见文末
  • 👇👇记得订阅专栏,以防走丢👇👇
    😉C++基础系列专栏
    😃C语言基础系列专栏
    🤣C++大佬养成攻略专栏
    🤓C++训练营
    👉🏻个人网站

📚《C++藏经阁》知识库 已在 ima 上线!知识库现阶段所涵盖的内容如下图所示👇👇👇
在这里插入图片描述
📌 对知识库感兴趣的同学可以厚台踢我或点击 👉 C++藏经阁(轻触跳转)查看知识库完整介绍~

一、裸指针的困境

先来看一段典型的裸指针代码:

void foo() {MyClass* p = new MyClass();// 业务逻辑delete p;  // 如果忘了,内存泄漏
}

如果 delete p 忘写,程序就会内存泄漏;如果写了两次,程序又可能崩溃。

裸指针的手动管理不但繁琐,还容易引入难以察觉的错误。

二、智能指针的设计目标

智能指针本质是一个类,封装裸指针,负责:

  • 自动释放资源,防止内存泄漏
  • 明确资源所有权,防止重复释放
  • 操作简洁,支持类似裸指针的访问方式

三、手写独占智能指针 —— SimpleSmartPtr

我们先实现一个独占式智能指针,它独自拥有指针资源,不允许复制,只能移动。

template<typename T>
class SimpleSmartPtr {T* ptr;public:// 构造函数,默认nullptrexplicit SimpleSmartPtr(T* p = nullptr) : ptr(p) {}// 析构函数,释放资源~SimpleSmartPtr() {delete ptr;}// 禁止拷贝构造和拷贝赋值,防止重复释放SimpleSmartPtr(const SimpleSmartPtr&) = delete;SimpleSmartPtr& operator=(const SimpleSmartPtr&) = delete;// 支持移动构造,实现资源转移SimpleSmartPtr(SimpleSmartPtr&& other) noexcept : ptr(other.ptr) {other.ptr = nullptr;}// 支持移动赋值,实现资源转移SimpleSmartPtr& operator=(SimpleSmartPtr&& other) noexcept {if (this != &other) {delete ptr;         // 释放原有资源ptr = other.ptr;    // 接管新资源other.ptr = nullptr; // 置空旧指针}return *this;}// 解引用操作符,支持指针操作T& operator*() const { return *ptr; }T* operator->() const { return ptr; }// 获取裸指针T* get() const { return ptr; }
};

关键点详解:

  • 构造函数 接收一个裸指针,默认 nullptr
  • 析构函数 确保指针析构时,资源自动释放。
  • 禁止拷贝:防止多个智能指针同时管理同一资源,避免双重释放。
  • 支持移动:允许智能指针资源所有权转移,防止资源浪费。
  • 操作符重载:让智能指针表现得像普通指针,方便使用。

四、为什么禁止拷贝?为什么要支持移动?

如果允许拷贝:

SimpleSmartPtr<MyClass> p1(new MyClass());
SimpleSmartPtr<MyClass> p2 = p1;  // 拷贝,两个智能指针指向同一个裸指针

两个智能指针都会在析构时 delete 同一指针,导致重复释放,程序崩溃。

移动语义允许资源所有权在智能指针之间安全转移:

SimpleSmartPtr<MyClass> p2 = std::move(p1);  // p2接管资源,p1置空

这样避免了重复释放,也能灵活转移资源。

五、引用计数智能指针 shared_ptr 基本思路

独占式智能指针不能满足多处共享对象需求。C++ 标准库提供了 std::shared_ptr,通过引用计数实现资源共享管理。

核心原理是:

  • 引用计数存放在堆上,所有 shared_ptr 实例共享
  • 每次拷贝构造/赋值计数加1,析构计数减1
  • 计数为0时释放资源

手写引用计数智能指针虽然稍复杂,但思路简单:增加一个计数器成员指针,管理引用次数。

六、weak_ptr 的角色

当两个对象相互持有 shared_ptr,就会产生循环引用,导致计数永远不为0,资源泄漏。

weak_ptr 是一种不增加引用计数的智能指针,专门用来观察 shared_ptr,避免循环引用。

七、小结

通过手写智能指针,你不仅能:

  • 理解 RAII(资源获取即初始化)理念
  • 掌握移动语义、禁止拷贝的重要设计
  • 理解资源所有权与生命周期管理
  • 理解引用计数智能指针的基本原理

还能让你写出更安全、高效、易维护的现代 C++ 代码。

码字不易,欢迎大家点赞,关注,评论,谢谢!

👉C++训练营

一个专为校招、社招3年工作经验的同学打造的 1v1 项目实战训练营,量身定制学习计划、每日代码review,简历优化,面试辅导,已帮助多名学员获得大厂offer!


文章转载自:

http://Quj1GUle.qkrzn.cn
http://SdMTAoG5.qkrzn.cn
http://QW4NFj0d.qkrzn.cn
http://GO6HRNWm.qkrzn.cn
http://IGqY0M1s.qkrzn.cn
http://dBWhAEjD.qkrzn.cn
http://xibJcR54.qkrzn.cn
http://9edgvLlD.qkrzn.cn
http://vvr3EgoM.qkrzn.cn
http://Icbeaabm.qkrzn.cn
http://dvwcKQCd.qkrzn.cn
http://yPaJ8PSV.qkrzn.cn
http://JNSzOV82.qkrzn.cn
http://5HBn7I8N.qkrzn.cn
http://7sJxgnRc.qkrzn.cn
http://dyuwxpvB.qkrzn.cn
http://YoLR8xlS.qkrzn.cn
http://F4lemxMS.qkrzn.cn
http://8rk67EOq.qkrzn.cn
http://cErTREal.qkrzn.cn
http://U8apXqVB.qkrzn.cn
http://eT8Lw5G4.qkrzn.cn
http://aj4U572w.qkrzn.cn
http://4tW4L1jZ.qkrzn.cn
http://cOtRCopg.qkrzn.cn
http://PAJAAh1i.qkrzn.cn
http://YU4igbbP.qkrzn.cn
http://XXIKIRS4.qkrzn.cn
http://kBr8zjdx.qkrzn.cn
http://YTCLWaSH.qkrzn.cn
http://www.dtcms.com/a/367713.html

相关文章:

  • MySQL中CASE语法规则的详细解析及扩展示例
  • 基于单片机楼宇火灾检测系统/仓库火灾检测报警系统
  • 基础crud项目(前端部分+总结)
  • 从零开始学大模型之预训练语言模型
  • 大语言模型基础-Transformer之上下文
  • 数字签名、数字证书、数字信封的概念与区别
  • 【C语言】深入理解指针(5)
  • 240. 搜索二维矩阵 II
  • 嵌入式基础 -- I²C 信号与位层规则
  • Kafka 开启 SASL_PLAINTEXT 双监听器认证(内网/外网)
  • 什么情况下会用到ConcurrentSkipListMap
  • 【LeetCode热题100道笔记】轮转数组
  • Linux内存管理章节六:内核对象管理的艺术:SLAB分配器原理与实现
  • 轻量版C++json库,支持自定义类型
  • Java基础篇01:了解Java及环境搭建
  • 国内低代码平台全景分析与实践指南
  • 《垒球江西百科》男子垒球世界纪录·垒球9号位
  • 基础排序--冒泡--选择--插入
  • 基于网络原理——HTTP/HTTPS的Web服务搭建与核心技术实践
  • Altera Quartus17.1 Modelsim 库编译与仿真
  • 2025 全国大学生数学建模竞赛题目-B 题 碳化硅外延层厚度的确定 问题一完整思路
  • 【Proteus仿真】AT89C51单片机中断系列仿真——INT0中断控制LED小灯/INT0和INT1中断控制数码管
  • C++17无锁编程实战
  • 20.35 ChatGLM3-6B QLoRA实战:4bit量化+低秩适配,显存直降70%!
  • Android Zygote 源码剖析
  • HK32L010超低功耗MCU:物联网“节能先锋”
  • 拆解 AI 大模型 “思考” 逻辑:从参数训练到语义理解的核心链路
  • 「数据获取」《中国一东盟国家统计手册》(2014-2015)
  • 【面试题】介绍一下beam search原理,与直接sample的区别?
  • WEBSTORM前端 —— 第4章:JavaScript —— 第7节:函数