一、为什么需要自定义 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++ 资源管理体系完整掌握区

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐