C++——C++11(2)

我在我的C++异常博客中曾提到,对于异常的处理经常会导致内存泄漏问题,
一种解决方法是异常的重新抛出,还有一种就是RAII,那么RAII的思想体现
在C++中就是智能指针,所以接下来我将简单的介绍,什么是RAII,以及什
么是智能指针。

1. 初识智能指针

在学C++的人,还没有接触智能指针的时候,就会想智能指针到底是什么啊?它真的是智能的吗?其实智能指针只是人们给它起了个这样的名字,它并不是智能的。
我们首先来解决异常博客中,如何使用RAII的思想很好的解决内存泄漏问题:
在这里插入图片描述
在这里插入图片描述
可以看到在程序执行中,只是开辟了空间,而没有释放。原因就是异常抛出后,如果有接收异常的地方,执行流会直接跳跃到匹配的catch中,而不执行中间栈帧的后续代码(但是会销毁中途的栈帧),而开辟空间是在堆上,自然也就无法释放了。接下来给出RAII思想解决内存泄漏问题:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到我们确实能够很好的将申请的资源释放,并且不需要我们自己手动释放。利用的原理也是当栈帧结束的时候,会调用栈帧中的自定义类的对象的析构函数,而我们利用这一点,正好可以将资源释放。而这可以说是RAII,但这也只是智能指针的雏形(因为它不具有指针的操作):
在这里插入图片描述

2. 智能指针的发展历程

智能指针其实在C++98中就有提出,只不过是在C++11中才被广泛认可。所以要研究好智能指针,顺着历史的发展来探索智能指针也未尝不可。

a. auto_ptr

在这里插入图片描述

auto_ptr是在C++98中提出的一种智能指针,它自然也遵循RAII。但是他有缺陷:
在这里插入图片描述
原因如下:
在这里插入图片描述
当使用赋值重载或者拷贝构造的时候,它会将资源的管理权转让,将原来的管理智能指针中的原生指针置为空,也就是对象悬空这样会导致使用者经常会出现访问越界的问题。这也是为什么C++11中智能指针才被广泛认可。
接下来我们简单实现一下auto_ptr:
在这里插入图片描述

在这里插入图片描述

b. unique_ptr

unique_ptr是C++11中提出的智能指针,它没有auto_ptr的缺点,因为它就不能将资源管理权进行转让(也就是无法使用赋值重载和拷贝构造)。
在这里插入图片描述
在这里插入图片描述

我们也可以试着自己实现一个简单的:
要实现对应的特性,我们可以只声明并且设为私有。
在这里插入图片描述
在这里插入图片描述
还有一种就是delete掉赋值重载和拷贝构造:

在这里插入图片描述

在这里插入图片描述
当然它也可以正常使用:
在这里插入图片描述

它的缺点也显而易见,就是同一处资源只能一个对象管理,所以就又有了shared_ptr。

c. shared_ptr

在这里插入图片描述
它的特点就是可以有多个shared_ptr对象共同管理同一处资源:
在这里插入图片描述
我们也可以自己实现,那么在实现的时候要实现多个对象共同管理一份资源,那就得使用引用计数了,但是这个引用计数的存储位置也必须是堆上开辟出来的,假如是成员变量的话就无法实现同一块资源有多少个shared_ptr对象管理了。假如是静态变量的话,如果程序中有两处资源需要shared_ptr管理也无法实现。
要注意:

计数只有在拷贝构造和赋值重载时才++。
析构时要根据引用计数来判断否真的释放资源。

实现如下:
在这里插入图片描述
在这里插入图片描述
它也有缺点:
在这里插入图片描述
在这里插入图片描述
可以看到这样设置节点是不正确的导致节点无法连接,所以应该是这样:
在这里插入图片描述
这样就会正常(这里多次释放不报错的原因是因为delete对空指针做了特殊处理):
在这里插入图片描述
但是这样就会出问题:
在这里插入图片描述
库中的也会出现这种问题:
在这里插入图片描述
在这里插入图片描述

这其中的逻辑如下:
在这里插入图片描述

就会导一直循环要释放从而无法释放资源。这种现象叫做循环引用。为了解决这种现象就又出现了weak_ptr。

weak_ptr

weak_ptr可以说是专门为了shared_ptr打辅助的,而它也不遵循RAII了。它其中提供了shared_ptr的构造函数,所以我们再来简单实现一手:
在这里插入图片描述
它没有析构函数,没有对资源进行管控,也就不遵循RAII,其中的get是获取shared_ptr的原生指针。
在这里插入图片描述
在这里插入图片描述
循环引用问题能够解决的原理是:使用weak_ptr之后没有增加两节点资源的引用计数,从而在析构时,能够很自然的释放资源

3. 定制删除器

在上面讲述中我们只是,delete了一块资源,那要是一块连续的资源呢?我们就需要使用delete[]来释放资源,那如何分别,究竟释放的是一块单一资源,还是一块连续的资源呢?C++把这个问题交给了程序员,所以就有了定制删除器,我们以unique_ptr举个例子:
在这里插入图片描述
这其中我们使用了可调用对象,包装器,模板来实现删除器的功能。

在这里插入图片描述
可以看到,不仅堆中的空间算资源,打开的文件也是资源,所以资源说的是很广泛的。

4. 总结

现在我们再回想一遍什么是RAII、智能指针?他们之间有什么关系?:

RAII它是一种思想,它其实就是利用了对象的生命周期的特点从而对资源达到控制。
而C++中的智能指针,它是RAII的一种体现,利用处于该栈帧中自定义类的析构函数
在栈帧结束时自动调用的特性,从而实现对资源的管控

而我们作为C++程序员,是必须要把内存泄漏这件事情看的非常非常非常重要的一件事:

1. 工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记着匹配的去释放。
ps:这个理想状态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。
需要下一条智能指针来管理才有保证。
2. 采用RAII思想或者智能指针来管理资源。
3. 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。
4 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/237253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络 网络层下 | IPv6 路由选择协议,P多播,虚拟专用网络VPN,MPLS多协议标签

文章目录 5 IPv65.1 组成5.2 IPv6地址5.3 从IPv4向IPv6过渡5.3.1 双协议栈5.3.2 隧道技术 6 因特网的路由选择协议6.1 内部网关协议RIP6.2 内部网关协议 OSPF基本特点 6.3 外部网关协议 BGP6.3.1 路由选择 6.4 路由器组成6.4.1 基本了解6.4.2 结构 7 IP多播7.1 硬件多播7.2 IP多…

Inscribe:应用非定向资产交易协议 布局巨大铭文赛道

随着比特币出现了一定的回调,铭文市场也出现了50%以上的跌幅,但是从市场的长期发展来看,铭文市场空间巨大,仍然是未来千亿级的蓝海市场,那么这样的回调阶段正式各类优质项目深度BUILD 扩展自己产品生态提升竞争力的关键…

还在用QQ拼音输入法吗?赶快卸载吧~!

最近总觉得我的C盘在莫名其妙的减少。之前的电脑C盘只有240G,所以我很在意C盘空间。但是,我发现买了新电脑,C盘空间也在莫名其妙减少。 随挨个文件夹检查。最后发现,QQ拼音的 dict 文件夹很大,居然有 30G多G。 30多~…

minio 整合springboot

pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

如何快速优化大数据量订单表

场景 本篇分享以前在广州一家互联网公司工作时遇到的状况及解决方案,这家公司有一个项目是SOA的架构,这个架构那几年是很流行的,哪怕是现在依然认为这个理念在当时比较先进。 当时的项目背景大概是这样,这家公司用的是某软提供的方案,项目已经运行3年多,整体稳定。 数据…

IPSec的起源-基础知识都需要掌握

IPSec的起源 目的 出于安全考虑。 最开始的互联网是明文通信&#xff0c;很容易被监听、篡改。添加了如crc一类的校验也不能完全保证数据的安全。 在IP层专门做的安全防护。 为什么是IP层&#xff1f;在当时IP层可通信的范围最广、应用最多。 开始也是从MAC层开始&#xff0c;后…

var let const的区别和使用场景?

var、let 和 const 是 JavaScript 中用于声明变量的关键字&#xff0c;它们之间有着一些区别和各自的使用场景。 var 作用域&#xff1a;var是在函数作用域&#xff08;function scope&#xff09;内声明的变量&#xff0c;如果在函数内部声明则只在函数内部有效&#xff0c;在…

中金汇融配资分享在线杠杆炒股的安全知识

随着股市的火爆&#xff0c;越来越多的人选择加入杠杆炒股的行列。然而&#xff0c;对于许多新手来说&#xff0c;如何安全有效地使用杠杆炒股却是一个难题。今天&#xff0c;我们就来为大家分享一家专业、安全、靠谱的在线杠杆炒股平台——中金汇融&#xff0c;让你轻松掌握在…

mysql mha高可用

一、前言 在原本的一主两从数据库架构中&#xff0c;是没有高可用功能的&#xff0c;当主库挂了时不会自动将剩下的从从升级为主库&#xff0c;只能等待主库恢复才能使用&#xff0c;或者手动切换&#xff0c;但是手动切换后需要更改后端服务中的数据库地址信息&#xff0c;在此…

架构设计到底是什么?

文章目录 架构设计有哪些内容&#xff1f;架构原理与技术认知分布式技术原理与设计中间件常用组件的原理和设计问题数据库原理与设计问题分布式缓存原理与设计问题互联网高性能高可用设计问题 技术认知架构分析问题分析能力边界 架构设计&#xff0c;是中高级研发工程师逃不开的…

C# 获取Excel里引用的外部其他excel文件清单

关键方法:mySheet.Application.ActiveWorkbook.LinkSources(XlLink.xlExcelLinks); 主要代碼如下 Application myExcel null;//引用Excel Application类別 Workbook myBook null;//引用活页簿类別 Worksheet mySheet null;//引用工作表类別 …

软件设计模式:单例模式

文章目录 前言一、单例模式实现1.饿汉式静态变量方式静态代码块方式 2.懒汉式线程不安全线程安全双重检查锁静态内部类方式枚举方式 二、存在问题1.序列化反序列化2.反射破坏3.解决序列化破坏解决反射破坏解决 三、JDK源码解析总结 前言 单例模式&#xff08;Singleton Patter…

windows远程桌面怎么开启?

文章目录 如下三种开启方式&#xff0c;任选一即可方式1.在系统属性中开启远程桌面方式2.通过系统设置开启远程桌面方式3.注册表编辑器开启远程桌面使用远程桌面 如下三种开启方式&#xff0c;任选一即可 配合 组网工具或者内网穿透 超级爽 局域网其他pc如何访问宿主机虚拟机IP…

@RequestParam、@PathVariable、@RequestBody、@RequestAttribute详解

一、RequestParam注解 作用&#xff1a;用于将指定的请求参数赋值给方法中的形参。 属性&#xff1a; 1&#xff09;value&#xff1a;请求参数名&#xff08;必须配置&#xff09; 2&#xff09;required&#xff1a;是否必需&#xff0c;默认为 true&#xff0c;即请求中必须…

Elasticsearch:什么是文本分类?

文本分类定义 - text classification 文本分类是一种机器学习&#xff0c;它将文本文档或句子分类为预定义的类或类别。 它分析文本的内容和含义&#xff0c;然后使用文本标签为其分配最合适的标签。 文本分类的实际应用包括情绪分析&#xff08;确定评论中的正面或负面情绪&…

GLTF/GLB模型在线预览、编辑、动画查看以及材质修改

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 GLTF在线编辑器提供了一个内置的模型查看器&#xff0c;可以加载和预…

Linux docker安装nacos

1&#xff1a;首先下载安装docker&#xff0c;这里不做描述&#xff0c;可以自行百度安装。 2&#xff1a;通过docker下载nacos&#xff0c; docker pull nacos/nacos-server:latest3&#xff1a;搭建临时nacos容器&#xff0c;此步骤的目的是为了获取nacos的配置文件和日志 …

Ubuntu 常用命令之 awk 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 AWK是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。在Ubuntu系统下&#xff0c;AWK命令主要用于数据处理和生成报告。 AWK命令的参数主要有 -F&#xff1a;指定输入文件分隔符&#xff0c;FS变量就是指定输入字…

【华为OD题库-094】最佳的出牌方法-java

题目 手上有一副扑克牌&#xff0c;每张牌按牌面数字记分(J11,Q12,K13&#xff0c;没有大小王)&#xff0c;出牌时按照以下规则记分: 出单张&#xff0c;记牌面分数&#xff0c;例如出一张2&#xff0c;得分为2 出对或3张&#xff0c;记牌面分数总和再x2&#xff0c;例如出3张3…

根据excel中的数据信息批量修改图片名称

背景说明 接了一个需求&#xff0c;需要将批量图片按照指定的需求进行重命名&#xff0c;本来的图片是以身份证号进行命名的.jpg文件&#xff0c;现在需要统一命名为班级姓名身份证号.png格式的文件。其中&#xff0c;用户提供了一张导出的excel数据表(data.xlsx)&#xff0c;数…