新闻详情

新闻详情

首页 / 资讯中心 / 详情

智能指针的原理及简单模拟实现(C++)

发布时间:2026/10/2 12:08:44来源:尧图网络
智能指针的原理及简单模拟实现(C++)
概念正如上一篇所说如果要对可能发生异常的都用catch(...)捕获一下那代码就会非常冗余如new可能也会抛出异常。这就是智能指针出现的缘由RAII是一种管理资源的类的设计思想——利用对象的生命周期管理指定动态资源内存、文件指针、网络连接、互斥锁等以防资源泄漏。详细点说就是RAII通过得到动态资源时将资源委托给一个对象保持资源在对象的生命周期内始终保持有效当对象生命周期结构系统自动调用的析构函数中释放资源有效防止了资源的泄漏问题原理C实现的智能指针在C标准库的memory中我们一起来学习一下在学习之前我们需要先明确我们会有暂时持有访问某个资源的需求如需要智能指针对象为实参要传给一个函数的形参以访问那个资源。如果我们只传这个指向资源的指针或者智能指针引用都无法覆盖所有场景需要考虑到智能指针的拷贝是深拷贝还是浅拷贝呢因为我们是为了管控资源肯定不可以深拷贝如果浅拷贝拷贝出来的对象析构那实参的对象再析构就会报错了首先是auto_ptr它是C98提出来的设计的比较糟糕当这个智能指针要拷贝另一个对象时会直接将管理权送给复制的对象相当于被复制的对象悬空了原auto_ptr类对象内部就变成了空指针我们无法再用。设计的十分糟糕在C11出现之前很多公司就明令禁止auto_ptrC11也增加了新的智能指针语法这个语法就不要使用了unique_ptr智能指针对象不能拷贝unique的汉语是唯一只能移动。如果不需要拷贝时建议使用shared_str智能指针对象可以拷贝也可以移动shared的汉语是共享。需要拷贝时就使用它。它的底层是增加了引用计数这一概念实现了多智能指针共同管理统一资源。引用计数——如果多一个对象指向此资源这个引用计数就如果此对象析构了引用计数--直到引用计数等于0时此时没有对象指向此资源这个资源就要释放weak_ptr创造出来是为了解决shared_ptr的一个问题文章后面再介绍它不是智能指针它不能管理资源智能指针默认是通过delete来释放资源但也可能会有其他形式的动态资源如C语言中的malloc等函数和文件操作、以及new[]都无法简单通过delete来释放C为智能指针增加了删除器概念删除器本质上是一个可调用对象如仿函数、lamda、函数不过shared_ptr是在构造时给删除器而unique_ptr是在类模板参数处给删除器。由于new[]使用频繁C将unique_ptr和shared_ptr都实现了特化这里的特化与前面讲的“shared_ptr的删除器要传给构造”要区分开是不同的方法unique_ptrDate[] up1(new Date[5]);shared_ptrDate[] sp1(new Date[5]);shared_ptr除了支持用指向资源的指针构造还支持make_shared用初始化资源对象的值直接构造我们可以大致将make_shared函数理解如下设计成可变参数模板是为了当类型如果是一个有较多成员变量的类时依然可用shared_ptr和unique_ptr都支持了operator bool的类型转换如果智能指针对象是一个空对象没有管理资源则返回false否则返回true意味着我们可以直接把智能指针对象给if判断是否为空shared_ptr和unique_ptr都得构造函数都使用explicit修饰防止普通指针隐式类型转换成智能指针对象普通指针隐式类型转换成智能指针对象看起来很方便但实际上很危险因为普通指针一旦被自动交给智能指针管理所有权关系可能变得非常不清楚模拟实现难点1、引用计数的类型是什么2、删除器加入到shared_ptr的构造函数后怎么让析构函数可以复用让删除器成为成员变量那么此成员变量是什么类型而且其默认删除器怎么设置下图只是简单模拟实现基本原理引用计数若是搭配weak_ptr实现起来会更复杂有兴趣的可以去查阅源码但是shared_ptr在这样的场景循环引用中会存在问题这样会出现内存泄漏问题sp1析构指向左侧链表结点的引用计数为1。sp2析构指向右侧链表结点的引用计数为1。左侧结点如果想释放需要右侧结点的_prev释放右侧结点的_prev若要释放需要右侧结点释放右侧结点若想释放需要左侧结点的_next释放左侧结点的_next若要释放需要左侧结点释放。哈哈是不是闭环了不倒翁。此时内存就会泄漏。C11为了解决此问题创造出了weak_ptrweak_ptr不支持RAll不会管理资源也不支持访问资源只支持绑定到shared_ptr绑定到shared_ptr时不增加shared_ptr的引|用计数此时就可以解决上述的循环引用问题为什么不管理资源呢它不会增加引用计数若它还指向资源如果资源已经释放了那么他去访问资源就是很危险的。weak_ptr有接口expired检查指向的资源是否过期资源是否释放use_count也可获取shared_ptr的引用计数weak_ptr想访问资源时可以调用lock返回一个管理资源的shared_ptr如果资源已经被释放返回的shared_ptr是一个空对象如果资源没有释放则通过返回的shared_ptr访问资源是安全的改造成这样循环引用的问题就解决了shared_ptr的还存在线程安全问题这里我还没学到等我学完了再来介绍
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

STM32开发实战:从时钟配置到外设验证的工程闭环 2026/10/2 16:54:49

STM32开发实战:从时钟配置到外设验证的工程闭环

1. 为什么“STM32简介”不是一张芯片参数表,而是一把打开嵌入式世界的钥匙你搜“STM32简介”,点开前十个结果,大概率看到的是:ARM Cortex-M内核、主频范围、Flash/RAM容量、外设列表……像一份电子元器件手册的摘录。但真正用过ST…

阅读更多 →
自定义鼠标指针样式:用 cursor 与 url() 打造个性化光标 2026/10/2 16:54:49

自定义鼠标指针样式:用 cursor 与 url() 打造个性化光标

1. 从一次「鼠标指针被吃掉」的线上问题说起 先说结论:CSS 的 cursor 属性配合 url(),能让你把默认箭头换成任意图标,但真正上线时翻车的往往不是语法,而是格式、尺寸、热点和回退链这四件事。这篇就围绕 cursor、css、url()、ico…

阅读更多 →
GPT-5.2 全面评测:对比 Gemini 3.0 与 Claude,三大模型实测与性能深度解析 2026/10/2 16:54:49

GPT-5.2 全面评测:对比 Gemini 3.0 与 Claude,三大模型实测与性能深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
STM32 GPIO与PWM的物理本质:从F103C8T6底层逻辑到工程落地 2026/10/2 16:54:49

STM32 GPIO与PWM的物理本质:从F103C8T6底层逻辑到工程落地

1. 什么是真正的“STM32理论”?——不是手册抄录,而是芯片底层逻辑的具象化理解很多人一看到“STM32理论”四个字,第一反应是翻《参考手册》第几章、背GPIO八种模式定义、默写HAL库函数原型。但我在带过37个嵌入式毕设小组、调试过210块F103C…

阅读更多 →
STM32CubeMX实战指南:从安装配置到SPI读写Flash与FreeRTOS集成 2026/10/2 16:54:49

STM32CubeMX实战指南:从安装配置到SPI读写Flash与FreeRTOS集成

STM32CubeMX 这个工具,估计每一个摸过 STM32 的开发者都绕不开。早年写 STM32 代码,最痛苦的就是对着参考手册手工配置寄存器,点灯都要翻半天 datasheet,更别说配置一个带 I2C、SPI、串口、定时器中断的项目,光初始化代…

阅读更多 →
Eclipse搭建C语言开发环境:CDT插件与MinGW工具链配置实战 2026/10/2 16:54:42

Eclipse搭建C语言开发环境:CDT插件与MinGW工具链配置实战

简介:EclipseCDTMinGW 是 Windows 下搭建 C/C 开发环境的常用组合方案,这份开发文档系统梳理了从软件下载、安装部署到参数配置的完整流程。资源先介绍 Eclipse SDK 与 CDT 的两种获取方式,再详细演示 MinGW 编译器安装及 Path、LIBRARY_PATH…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉