自定义删除器与 make 函数
使用 std::make_unique、std::make_shared 和自定义删除器管理非内存资源
自定义删除器与 make 函数 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
为什么需要自定义删除器
并非所有资源都通过 delete 释放。文件句柄、套接字、OS 特定资源和数组都需要使用不同的清理函数。
unique_ptr 的默认删除器
默认情况下,unique_ptr<T> 使用 delete。对于数组,请使用 unique_ptr<T[]>,它会调用 delete[]。
指定自定义删除器
请将可调用对象作为第二个模板参数传入。删除器会接收原始指针,并以适当的方式释放它。
auto closer = [](FILE* f) { if (f) std::fclose(f); };
std::unique_ptr<FILE, decltype(closer)> file(
std::fopen("data.txt", "r"), closer);shared_ptr 的删除器
shared_ptr 会将删除器存储在控制块中——删除器的类型会经过类型擦除,因此 shared_ptr 类型本身不会改变。
std::shared_ptr<FILE> file(
std::fopen("data.txt", "r"),
[](FILE* f) { if (f) std::fclose(f); }
);自定义删除器的常见使用场景
实际使用中的示例:
- C 库句柄(FILE*、sqlite3*、curl 句柄)
- OS 资源(Windows 上的 HANDLE、Unix 上的 fd)
- 自定义内存池
- 带引用计数的外部对象
std::make_unique(C++14)
创建 unique_ptr 的推荐方式。它会将参数转发给构造函数,并避免直接使用原始 new。
auto p = std::make_unique<Widget>(arg1, arg2);为什么使用 make_unique
它有三项好处:
- 异常安全——用户代码中不需要使用原始
new - 无需重复书写类型
- 不会意外地将原始指针传给两个 unique_ptr
std::make_shared
对于 shared_ptr,make_shared 会在一次堆分配中同时分配控制块和对象——比分别分配更快。
auto p = std::make_shared<Widget>(arg1, arg2);make_shared 的不足之处
由于只有一次分配,对象占用的内存只有在所有 weak_ptr 也都销毁后才会释放。如果您的 weak_ptr 的生命周期超过了 shared_ptr,请优先采用分两步构造的方式。
将自定义删除器与 make 函数结合使用
make_unique 和 make_shared 不直接接受自定义删除器。在这种情况下,请手动构造智能指针。
// make_shared cannot take a deleter
std::shared_ptr<FILE> file(
std::fopen("data.txt", "r"),
[](FILE* f) { if (f) std::fclose(f); }
);陷阱:将 Lambda 类型用作模板参数
每个 Lambda 都有唯一的类型。对于 unique_ptr,声明时请使用 decltype(my_deleter);或者使用具名函数或函数指针,以简化类型。
快速检查
哪个工厂函数可以在一次堆分配中同时分配 std::shared_ptr 及其控制块?
回顾
在常规情况下,请使用 make_unique 和 make_shared。当资源需要的不只是 delete 时,请提供自定义删除器(Lambda 或函数)——例如文件句柄、OS 对象或 C 库清理操作。
用 AI 导师学习 C++ — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 51
- 课程
- 203
常见问题解答
「自定义删除器与 make 函数」课时是免费的吗?
是的 — 「自定义删除器与 make 函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「自定义删除器与 make 函数」这节课中我会学到什么?
使用 std::make_unique、std::make_shared 和自定义删除器管理非内存资源 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「自定义删除器与 make 函数」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。