C++ 自定义 Deleter 彻底讲透(从 delete 到通用资源管理)
C++智能指针的自定义Deleter机制允许指定资源的释放方式,突破默认delete的限制。通过自定义Deleter,智能指针可以管理各种资源(文件、malloc内存、socket等)的释放逻辑。unique_ptr的Deleter是类型的一部分,而shared_ptr的Deleter存储在控制块中。这一机制扩展了RAII的能力,使智能指针成为"带所有权+释放策略的资源管理对象"
一、为什么需要自定义 Deleter?
在 C++ 中,我们常见的资源管理是这样的:
User* p = new User();
delete p;
👉 这里默认规则是:
new → delete
但是现实开发中:很多资源根本不是用 delete 释放的
常见资源与释放方式
| 资源类型 | 创建方式 | 释放方式 |
|---|---|---|
| 对象 | new | delete |
| 数组 | new[] | delete[] |
| malloc 内存 | malloc | free |
| 文件 | fopen | fclose |
| socket | socket | close |
👉 问题来了:❗智能指针默认只会 delete,这些资源怎么办?
二、核心结论(必须记住)
自定义 deleter = 指定资源的释放方式
👉 默认:
unique_ptr → delete ptr
👉 自定义:
unique_ptr → 你提供的函数(ptr)
三、默认行为 vs 自定义行为
默认 unique_ptr
std::unique_ptr<User> p(new User());
析构时:
delete p
自定义 deleter
std::unique_ptr<User, Deleter> p(ptr, deleter);
析构时:
deleter(ptr)
👉 本质变化: 释放策略从“固定 delete” → “可配置”
四、最经典例子:文件管理
❌ 错误写法
std::unique_ptr<FILE> fp(fopen("a.txt", "r"));
👉 问题:
析构时 → delete FILE* ❌(错误)
✅ 正确写法
#include <memory>
#include <cstdio>
std::unique_ptr<FILE, decltype(&fclose)> fp(
fopen("a.txt", "r"),
fclose
);
👉 析构时:
fclose(fp)
五、malloc 示例
std::unique_ptr<int, decltype(&free)> p(
(int*)malloc(sizeof(int)),
free
);
👉 析构:
free(ptr)
六、你必须理解的核心变化
默认
delete ptr
自定义
Deleter(ptr)
👉 本质:
智能指针不仅管理指针,还管理“释放规则”
七、shared_ptr 也支持 deleter
std::shared_ptr<int> p(
(int*)malloc(sizeof(int)),
free
);
👉 释放时:
引用计数 = 0 → 调用 free
👉 注意:
deleter 存在 控制块 中
八、unique_ptr vs shared_ptr 的 deleter 区别
| 类型 | deleter 存储位置 |
|---|---|
| unique_ptr | 类型的一部分 |
| shared_ptr | 控制块中 |
👉 你不用死记,只要理解:
两者都支持自定义释放逻辑
九、你要建立的核心认知
👉资源 ≠ 一定是 new 出来的对象
👉 C++ 管的不是“对象”,而是: 所有资源
十、工程级理解(非常关键)
你以后会遇到的资源:
文件(FILE)
网络连接(socket)
数据库连接
锁(mutex)
第三方库句柄
👉 这些都需要: 自定义释放逻辑
十一、智能指针真正做的两件事
1️⃣ 管理指针(谁拥有)
2️⃣ 管理释放(怎么释放)
👉 默认:
delete
👉 自定义:
你决定
十二、为什么一定要有 deleter?
👉 因为:
RAII 想要管理所有资源,就必须支持不同释放方式
👉 所以:deleter = RAII 的扩展能力
十三、终极总结(必须记住)
智能指针的本质不是“更聪明的指针”,而是“带所有权 + 释放策略的资源管理对象”
面试总结
Q:什么是自定义 deleter?
自定义 deleter 是智能指针的一种机制,用于指定资源释放方式,使其不仅能管理 new 创建的对象,还可以管理文件、malloc 内存、socket 等其他资源。
Q:为什么需要?
因为不同资源有不同的释放方式,而默认 delete 无法覆盖所有场景。
Q:unique_ptr 和 shared_ptr 的区别?
unique_ptr 的 deleter 是类型的一部分,而 shared_ptr 的 deleter 存储在控制块中。
结尾
当你理解了 deleter,本质上你已经完成了:
RAII ✔
move ✔
unique_ptr ✔
shared_ptr ✔
weak_ptr ✔
deleter ✔
👉 你已经进入:
C++ 资源管理体系完整掌握区
更多推荐


所有评论(0)