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

【C++系列】智能指针自定义析构

在 C++ 中,智能指针(如 std::unique_ptr 和 std::shared_ptr)允许自定义析构函数(称为 ​​deleter​​),用于在释放资源时执行特定操作。

1. std::unique_ptr 自定义析构函数

​原理​
std::unique_ptr 的模板包含两个参数:

template<class T, class Deleter = std::default_delete<T>> 
class unique_ptr;
  • Deleter 类型​​:可调用对象(函数、Lambda、函数对象),接收 T* 参数。

  • 示例 1:使用函数作为删除器
#include <iostream>
#include <memory>// 自定义删除函数
void FileDeleter(FILE* file) {if (file) {std::cout << "Closing file\n";fclose(file); // 关闭文件}
}int main() {// 自定义删除器类型: decltype(&FileDeleter)std::unique_ptr<FILE, decltype(&FileDeleter)> file(fopen("test.txt", "w"), FileDeleter // 传入删除器函数);// 当 file 超出作用域时,自动调用 FileDeleter
}
  • 示例 2:使用 Lambda 作为删除器

auto deleter = [](FILE* f) {std::cout << "Lambda closes file\n";if (f) fclose(f);
};int main() {// decltype(deleter) 获取 Lambda 类型std::unique_ptr<FILE, decltype(deleter)> file(fopen("test.txt", "w"), deleter // 传入 Lambda);
}
  • 示例 3:使用函数对象(仿函数)

struct FileDeleter {void operator()(FILE* f) const {std::cout << "Functor closes file\n";if (f) fclose(f);}
};int main() {// 指定删除器类型 FileDeleterstd::unique_ptr<FILE, FileDeleter> file(fopen("test.txt", "w")// 构造时可不显式传递,默认构造删除器对象);
}

 

2. std::shared_ptr 自定义析构函数

​原理​
std::shared_ptr 的删除器通过构造函数传入,​​不影响类型​​,因此更灵活:

template<class Y, class Deleter>
shared_ptr(Y* ptr, Deleter d);

示例:管理动态数组

#include <iostream>
#include <memory>int main() {// 删除器:用 delete[] 释放数组auto deleter = [](int* p) {std::cout << "Deleting array\n";delete[] p;};// 共享指针管理数组std::shared_ptr<int> arr(new int[10], deleter);// 等效写法:直接用 unique_ptr 管理数组// std::unique_ptr<int[]> arr(new int[10]); // 内置数组支持
}

常见应用场景

  • ​文件句柄

std::unique_ptr<FILE, decltype(&fclose)> file(fopen("a.txt", "r"), fclose);
  • 动态数组(需手动释放)
std::shared_ptr<int> arr(new int[10], [](int* p) { delete[] p; });
  •  ​​互斥锁(自动解锁)
std::unique_ptr<std::mutex, std::function<void(std::mutex*)>> lockPtr(&mtx, [](std::mutex* m) { m->unlock(); });
  • ​C 资源(如 OpenSSL 对象)
std::unique_ptr<BIO, decltype(&BIO_free)> bio(BIO_new(...), BIO_free);

关键注意事项

  1. unique_ptr 的删除器是类型的一部分​

    • 不同删除器的 unique_ptr 属于不同类型。
    • 例如:unique_ptr<int, DeleterA> 和 unique_ptr<int, DeleterB> 不兼容。
  2. shared_ptr 的删除器不影响类型​

    • 所有 shared_ptr<T> 无论删除器如何,类型相同。
    • 删除器存储在控制块中,动态调用。
  3. ​空指针与删除器​
    删除器需处理指针为空的情况。

  4. ​性能影响​

    • unique_ptr 的删除器通常无额外开销(可内联)。
    • shared_ptr 的删除器存储在堆上,略有开销。
http://www.xdnf.cn/news/931717.html

相关文章:

  • 如何将淘宝店铺商品搬到抖店去?利用 API 实现淘宝店铺商品到抖店的高效迁移
  • 5-C#的DateTime使用
  • Web后端基础(基础知识)
  • 基于PTN传输承载的4G网络-故障未连接...(我不理解哪错了排查了几遍没发现哪错啊啊啊啊)
  • AI架构师如何创建自己的知识库
  • JS手写代码篇---手写ajax
  • 计组_导学
  • 云备份项目
  • 行为型设计模式之Mediator(中介者)
  • java面试:JAVA并发篇
  • android计算器代码
  • uni-app学习笔记二十四--showLoading和showModal的用法
  • 自然语言处理——文本表示
  • 泛型约束:用于限制泛型类型参数的范围
  • 力扣HOT100之二分查找:4. 寻找两个正序数组的中位数
  • 深入解析 Pandas 核心数据结构:Series 与 DataFrame
  • ubuntu 安装 sougou
  • c++ 头文件
  • iview组件库:当后台返回到的数据与使用官网组件指定的字段不匹配时,进行修改某个属性名再将response数据渲染到页面上的处理
  • 海思Hi3798MV310_V39_HMS DDR3_安卓9.0_外贸盒update升级包
  • ALOHA ACT算法与源码笔记
  • Keil进阶操作
  • 前沿探索:可视化助力设备运维实现跨越式发展
  • JAVA反序列化应用 : URLDNS案例
  • 前端获取接口数据流程
  • 二分答案-P1873 砍树
  • MySQL中的部分问题(2)
  • Spring整合Mybatis
  • WEB3全栈开发——面试专业技能点P3JavaScript / TypeScript
  • 数据库、数据仓库、数据中台、数据湖相关概念