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

C++ 智能指针实现原理

C++ 智能指针是通过 RAII(资源获取即初始化)技术来管理动态分配内存的工具,它能避免手动管理内存时常见的内存泄漏问题。下面详细介绍其两大核心机制:引用计数和自定义删除器。

一、 引用计数原理

引用计数是智能指针实现资源自动释放的基础机制。其工作流程如下:

  1. 当一个智能指针被创建并指向某个资源时,该资源的引用计数初始化为 1。
  2. 当智能指针被复制(如赋值给其他智能指针)或作为参数传递时,引用计数加 1。
  3. 当智能指针被销毁(如离开作用域)或被重置为指向其他资源时,引用计数减 1。
  4. 当引用计数降为 0 时,表示没有智能指针再引用该资源,此时自动释放该资源。

这种机制确保了资源的生命周期与引用它的智能指针数量严格绑定。C++ 标准库中的 std::shared_ptrstd::weak_ptr 就是基于引用计数实现的。

二、自定义删除器

默认情况下,智能指针在引用计数为 0 时会使用 delete 操作符释放资源。但对于一些特殊资源,如文件句柄、网络连接等,需要自定义释放方式,这时就可以使用自定义删除器。自定义删除器允许用户指定一个可调用对象(函数、函数对象或 Lambda 表达式),在资源释放时调用该对象来执行特定的清理操作。

三、 示例代码

下面是一个简单的示例,展示了引用计数和自定义删除器的用法:

#include <iostream>
#include <memory>// 自定义资源类,用于演示
class Resource {
public:Resource(int id) : id_(id) {std::cout << "Resource " << id_ << " created" << std::endl;}~Resource() {std::cout << "Resource " << id_ << " destroyed" << std::endl;}void use() const {std::cout << "Using resource " << id_ << std::endl;}
private:int id_;
};// 自定义删除器函数
void customDeleter(Resource* res) {std::cout << "Custom deleting resource" << std::endl;delete res;
}int main() {// 创建一个 shared_ptr,使用自定义删除器std::shared_ptr<Resource> ptr1(new Resource(1), customDeleter);std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;// 复制 shared_ptr,引用计数增加std::shared_ptr<Resource> ptr2 = ptr1;std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;std::cout << "ptr2 use count: " << ptr2.use_count() << std::endl;// 使用资源ptr1->use();ptr2->use();// 重置 ptr2,引用计数减少ptr2.reset();std::cout << "After reset ptr2:" << std::endl;std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;// ptr1 离开作用域,引用计数变为 0,资源被释放return 0;
}

四、代码解释

  1. 引用计数演示

    • ptr1 创建时引用计数为 1。
    • ptr2 复制 ptr1 后,两者引用计数都变为 2。
    • ptr2.reset() 使 ptr2 不再引用资源,ptr1 的引用计数变回 1。
    • ptr1 离开作用域时,引用计数降为 0,资源被释放。
  2. 自定义删除器演示

    • 通过 std::shared_ptr 的第二个参数传入 customDeleter 函数。
    • 当资源释放时,会先调用 customDeleter 函数,再执行实际的资源释放操作。

通过这种方式,C++ 智能指针提供了一种安全且灵活的内存管理方式,既能自动管理资源生命周期,又能适应各种特殊资源的释放需求。

http://www.xdnf.cn/news/965845.html

相关文章:

  • [一生一芯] 如何基于iSTA 分析时序
  • 3-存储系统
  • 【OpenCV】双相机结构光成像与图像交叉融合实现【C++篇】
  • 【Qt】Qt生成的exe依赖库与打包
  • 一天时间解决期末不挂科
  • 人工智能增强入侵检测系统以对抗高级持续性杀伤链
  • CTF show Web 红包题第六弹
  • 条件概率:AI大模型概率统计的基石
  • 第二讲 认识变量及数学运算符
  • 《广度优先搜索》题集
  • 一个n8n构建的能和LLM对话的Agent
  • mybatics
  • LCS4110R安全芯片防抄板原理
  • 黑马python(三)
  • 手写muduo网络库(三):事件分发器(Poller,EPollPoller实现)
  • java复习 07
  • C#设计模式
  • 用Python实现卡片人探险游戏:能量采集与生存挑战
  • Spring Boot 4.0.0 新特性详解:深入解读 Spring Framework 7.0.0
  • flutter基础面试知识汇总(二)
  • linux 错误码总结
  • HMTL+CSS+JS-新手小白循序渐进案例入门
  • 期末考试复习总结-《ArkTS基础语法(上)》
  • 无人机机器人资源整合
  • ETL中图表统计分析模版组件使用
  • CppCon 2015 学习:C++ WAT
  • 无人机动力系统核心技术解析
  • leetcode240-搜索二维矩阵
  • 搜索二维矩阵
  • Java八股文——MyBatis篇