c++中的std::unique_ptr的deleter怎么自定义_c++智能指针高级用法【技巧】

发布时间 - 2025-12-25 00:00:00    点击率:
自定义 std::unique_ptr 的 deleter 是让指针释放时执行指定逻辑而非仅 delete;支持函数指针、lambda、functor 等可调用类型,需在模板参数中显式声明 deleter 类型。

自定义 std::unique_ptr 的 deleter,核心是让指针在释放资源时执行你指定的逻辑,不只是简单调用 delete

deleter 的类型和写法

deleter 可以是函数指针、函数对象(functor)、lambda 表达式,或任何可调用类型,只要它接受一个参数(指针类型)且无返回值。

  • 函数指针:需提前声明函数,签名形如 void my_deleter(int* p)
  • lambda:最常用,捕获灵活,适合带状态的清理逻辑(比如记录日志、关闭句柄)
  • functor:适合复用、需保存内部状态的场景(如计数器、资源池管理)

基本用法:模板参数显式指定 deleter 类型

必须在 unique_ptr 模板中声明 deleter 类型,否则编译失败:

auto del = [](int* p) { 
    std::cout << "Deleting: " << *p << "\n"; 
    delete p; 
};
std::unique_ptr ptr(new int(42), del);

注意:不能只写 std::unique_ptr 然后传 lambda 构造——类型不匹配。必须把 decltype(del) 显式作为第二个模板参数。

避免手动写 decltype:用 make_unique 的替代方案

C++14 起没有直接支持自定义 deleter 的 make_unique,但可以封装辅助函数:

template 
auto make_unique_with_deleter(Deleter&& d) {
    return std::unique_ptr>(
        new T(), std::forward(d)
    );
}
// 使用
auto ptr = make_unique_with_deleter([](int* p) { delete p; });

这样就不需要反复写 decltype,也避免了类型推导错误。

常见实用场景

  • 释放 C 风格资源:如 fopen / fclose,用 std::unique_ptr
  • 数组管理:用 std::default_delete 替代默认的 delete(防止未定义行为)
  • 共享所有权模拟:deleter 中调用 release() 或触发回调,实现“最后释放时才真正销毁”
  • 调试追踪:deleter 打印地址、计数、校验资源状态,排查泄漏或重复释放

基本上就这些。关键不是“怎么写”,而是想清楚:资源谁分配、谁释放、释放时要做什么——deleter 就是你掌控释放环节的钩子。


# c++  # 封装  # fopen  # fclose  # int  # void  # Lambda  # 指针  # 指针类型  # delete  # 对象  # 自定义  # 句柄  # 就不  # 做什么  # 第二个  # 而非  # 时要  # 时才  # 回调  # 最常用 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  Laravel如何实现全文搜索功能?(Scout和Algolia示例)  Laravel storage目录权限问题_Laravel文件写入权限设置  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  如何在服务器上配置二级域名建站?  如何用PHP快速搭建CMS系统?  如何在万网主机上快速搭建网站?  zabbix利用python脚本发送报警邮件的方法  Linux网络带宽限制_tc配置实践解析【教程】  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  活动邀请函制作网站有哪些,活动邀请函文案?  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  如何在阿里云虚拟主机上快速搭建个人网站?  开心动漫网站制作软件下载,十分开心动画为何停播?  Laravel如何实现数据库事务?(DB Facade示例)  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  如何快速搭建高效香港服务器网站?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复  如何在云服务器上快速搭建个人网站?  高防服务器:AI智能防御DDoS攻击与数据安全保障  EditPlus中的正则表达式 实战(4)  高防服务器租用指南:配置选择与快速部署攻略  iOS发送验证码倒计时应用  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  如何为不同团队 ID 动态生成多个“认领值班”按钮  如何实现建站之星域名转发设置?  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  Laravel如何处理异常和错误?(Handler示例)  如何确保西部建站助手FTP传输的安全性?  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  如何快速生成凡客建站的专业级图册?  英语简历制作免费网站推荐,如何将简历翻译成英文?  bootstrap日历插件datetimepicker使用方法  Python数据仓库与ETL构建实战_Airflow调度流程详解  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门  MySQL查询结果复制到新表的方法(更新、插入)  如何在万网自助建站平台快速创建网站?  Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程  如何在Tomcat中配置并部署网站项目?  标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  如何快速生成专业多端适配建站电话?  黑客如何利用漏洞与弱口令入侵网站服务器?  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  如何制作一个表白网站视频,关于勇敢表白的小标题?  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程