为“异常”努力是值得的

异常是OO语言处理错误的方式,在C++中,鼓励使用异常。侯捷再书中谈起异常,“十年前撰写“未将异常考虑在内的”函数是为一种美好实践,而今我们致力于写出“异常安全码”。”可见异常安全的重要。

说起异常安全,首先就要是异常的出现是为弥补C语言缺陷。再者,将介绍异常的概念,异常安全的条件。

C语言处理错误的缺陷

  • 程序意外终止

                比如:内存申请错误,越界,除0错误,会直接终止程序

  • 错误码难以解读

                在出错后会返回一个数字(错误码)。此时会包含俩层含义:是错误信息?是结果?

                错误码需要程序员查找相关库信息

     出现错误直接终止程序是非常不允许的情况。

C++异常的引入

异常:当一个函数出现自己无法解决的错误时,可以抛出异常,让函数的直接或间接调用者处理这个问题。

处理异常的三个关键字:

throw:当问题出现时,要抛出异常,通过throw抛出

catch:用于捕获异常。可以有多个catch

try:try中的代码将被激活特定的异常,try后跟着一个或多个catch块。

try要和catch匹配使用。

catch块中的内容不一定会被执行,只有当异常抛出且被捕获时才会执行,否则不执行。

	try {//保护块}catch (ExceptionName e1){//}catch (ExceptionName e2){//}

异常的抛出与匹配规则

  • 异常是有抛出对象引发的,该对象类型决定调用哪个块的。比如:抛出int类型的异常,catch参数为int的来接收。实际上:抛出和捕获类型不一定要相同,这里可以抛出派生对象。


  • 选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。


  • 异常抛出的对象后,会生成一个临时拷贝,传给catch

在实际运用中,抛异常抛出通常对象是一个类,包含错误信息和错误码。

由于私有成员在内外拿不到,故通过函数调用返回错误信息和错误码。

对于临时拷贝的类型是const 故函数要添加const,才可调用。


  • catch(...)可以捕获任意类型的对象。

抛出的异常在没有继承情况下,要匹配相应的类型才能被捕获,会在catch中一直匹配,直到catch(...)处理任意类型。但是无法得到抛出的异常对象。

异常的重新抛出

对于内存资源申请,抛异常要极为谨慎。
在上述的例子中,虽然有对内存资源释放,但是抛异常后捕捉异常跨越栈帧,导致内存没有被释放。内存的申请没有释放是一件很严重的事情。
在这里,希望能在main函数中,将内存释放。
我们必须将异常重新抛出,在Func函数中,捕获异常,再将异常重新抛出。

异常安全


具有异常安全的函数会

  • 不泄露任何资源。例如上述代码在抛出异常后,后续的delete不会被调用。
  • 不允许数据败坏。异常抛出后,异常被捕获,导致栈帧的跳跃,关键信息没有被执行。

解决资源泄露是比较轻松的

确保析构,智能指针。

这里我们专注解决数据败坏的问题。

在构造函数中,最好不要抛异常,可能会导致没有完全构造

析构过程最好不好抛异常

在lock和unlock抛异常会导致死锁

异常安全函数有以下三个保证

  • 基本承诺

        如果异常被抛出,程序内任何事物都保持在有效状态,没有任何对象和数据结构被破坏,所有对象处于一种内部前后一致的状态。

  • 强烈保证

        如果函数调用成功,就完全成功。如果函数失败,程序就恢复到调用之前状态。

  • 不抛掷保证

        承诺异常绝不抛出,因为它们总能够完成它们原先承诺的功能。

在C++11中,如果一个函数明确的不抛异常的话,就用noexcept

thread() noexcept;
thread (thread&& x) noexcept;

异常优点

  • 可以清晰展示错误信息
  • 抛异常可以直接拿到错误信息,不需要重重返回。
  • 第三方库的异常安全很规范
  • 部分函数更好检查。如构造函数没有返回值。

缺点

执行的跳跃,乱流。追踪程序困难。

C++没有垃圾回收机制,异常任意导致内存泄漏

标准库的异常不完善。

异常是被鼓励使用。时间不断前进,我们与时俱进!

参考:
<<Effective c++>>

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

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

相关文章

Leetcode—213.打家劫舍II【中等】

2023每日刷题&#xff08;五十二&#xff09; Leetcode—213.打家劫舍II 算法思路 实现代码 class Solution { public:// 左闭右开int rob1(vector<int>& nums, int start, int end) {int n nums.size();int f0 0, f1 0, new_f 0;for(int i start; i < end…

机器学习硬件十年:性能变迁与趋势

本文分析了机器学习硬件性能的最新趋势&#xff0c;重点关注不同GPU和加速器的计算性能、内存、互连带宽、性价比和能效等指标。这篇分析旨在提供关于ML硬件能力及其瓶颈的全面视图。本文作者来自调研机构Epoch&#xff0c;致力于研究AI发展轨迹与治理的关键问题和趋势。 &…

【送书活动四期】被GitHub 要求强制开启 2FA 双重身份验证,我该怎么办?

记得是因为fork了OpenZeppelin/openzeppelin-contracts的项目&#xff0c;之后就被GitHub 要求强制开启 2FA 双重身份验证了&#xff0c;一拖再拖&#xff0c;再过几天帐户操作将受到限制了&#xff0c;只能去搞一下了 目录 2FA是什么为什么要开启 2FA 验证GitHub 欲在整个平台…

消息队列 - RabbitMQ

消息队列 - RabbitMQ 1. 初识 MQ1.1 同步调用1.2 异步调用1.3.技术选型 2. RabbitMQ2.1 安装2.2 收发信息2.2.1 交换机(Exchange)2.2.2 队列2.2.3 绑定关系2.2.4 发送消息 2.3 数据隔离 1. 初识 MQ 微服务一旦拆分&#xff0c;必然涉及到服务之间的相互调用&#xff0c;之前讲…

编译 Android gradle-4.6-all.zip 报错问题记录

编译 Android gradle-4.6-all.zip 报错问题记录 方法一&#xff1a;替换资源&#xff1a;方法二&#xff1a;修改源方法三&#xff1a;修改版本 编译时候无法下载 gradle-4.6-all Downloading https://services.gradle.org/distributions/gradle-4.6-all.zip 方法一&#xf…

《一念关山》热度破万,爱奇艺古装赛道出尽风头

​刘诗诗重回古装剧、新式武侠公路片、质感细腻的镜头美学......看点满满的《一念关山》频频登上热搜&#xff0c;俘获了大批观众的心。 开播首日热度就刷新了爱奇艺2023年站内纪录&#xff0c;《一念关山》作为2023年爱奇艺在古装赛道的收官之作&#xff0c;口碑和热度兼收。…

一文详解Java反射

文章目录 反射是什么&#xff1f;反射的作用所有方法汇总一、加载Class对象二、加载类的构造器对象三、加载类的成员变量四、加载类的成员方法 反射是什么&#xff1f; 反射就是&#xff1a;加载类&#xff0c;并允许以编程的方式解剖类中的某个成分&#xff08;成员变量&#…

实战:Docker Compose 下 Nginx、Java、Mysql 和 Redis 服务协同部署(包含解决浏览器访问Linux部署服务器本地资源问题)

1. 背景 在该实战中&#xff0c;我们将探讨如何使用Docker Compose协同部署Nginx、Java、Mysql和Redis服务&#xff0c;实现一个视频上传与展示的应用。具体需求如下&#xff1a; Java应用负责上传视频和图片资源到Nginx目录下&#xff0c;作为资源服务器。Nginx服务作为静态…

Numpy数组常用属性汇总(第5讲)

Numpy数组常用属性汇总 (第5讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ…

【JavaEE进阶】 Spring使用注解存储对象

文章目录 &#x1f334;序言&#x1f340;前置⼯作&#xff1a;配置扫描路径&#x1f384;添加注解存储 Bean 对象&#x1f333;类注解&#x1f6a9;为什么要这么多类注解&#x1f6a9;注解之间的联系 &#x1f38b;⽅法注解 Bean&#x1f6a9;⽅法注解需要配合类注解使⽤ ⭕总…

探索AIGC未来:CPU源码优化、多GPU编程与中国算力瓶颈与发展

★人工智能&#xff1b;大数据技术;AIGC;Turbo;DALLE 3;多模态大模型&#xff1b;MLLM&#xff1b;LLM&#xff1b;Agent&#xff1b;Llama2&#xff1b;国产GPU芯片&#xff1b;GPU;CPU&#xff1b;高性能计算机&#xff1b;边缘计算&#xff1b;大模型显存占用&#xff1b;5G…

中国特供阉割版 RTX 4090 曝光,老黄这操作绝了

到了现在大伙儿应该发现&#xff1a;国内禁售 NVIDIA RTX 4090 显卡这事儿基本实锤了。 实际上根据老美规定&#xff0c;从上个月 17 号开始&#xff0c;凡是公司主体在中国的显卡品牌&#xff0c;就已经不能生产和销售 RTX 4090。 以后厂商想要卖 4090 只能以整机形式出售&am…

艺术画廊展厅网站制作的效果如何

艺术展厅往往有很多人前往&#xff0c;在主要城市有不少画廊&#xff0c;对经营者来说&#xff0c;不同于销售行业&#xff0c;其更多的是打造品牌吸引用户前来或合作等形式&#xff0c;而由于行业特殊性&#xff0c;需要准属性用户才会前往。 因此在品牌打造及信息承载宣传方…

防止企业敏感数据泄露

敏感数据泄露是指意外或故意泄露关键信息&#xff0c;例如个人身份信息&#xff08;PII&#xff09;、支付卡信息&#xff08;PCI&#xff09;、受保护的电子健康信息&#xff08;ePHI&#xff09;和知识产权&#xff08;IP&#xff09;&#xff0c;数据保护措施不足的组织会在…

Spark---DataFrame存储、Spark UDF函数、UDAF函数

四、DataFrame存储Spark UDF函数 1、储存DataFrame 1&#xff09;、将DataFrame存储为parquet文件 2&#xff09;、将DataFrame存储到JDBC数据库 3&#xff09;、将DataFrame存储到Hive表 2、UDF&#xff1a;用户自定义函数 可以自定义类实现UDFX接口 java&#xff1a; …

案例062:基于微信小程序的健身房私教预约系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

模块式雨水调蓄池施工简单,无需大型机械,可实现当天开挖当天回填

模块式雨水调蓄池的施工过程非常简单&#xff0c;无需大型机械和繁琐的施工工艺。在施工过程中&#xff0c;只需要进行简单的开挖和回填即可&#xff0c;而且可以在当天完成。这种施工方式不仅节省了施工时间和成本&#xff0c;还可以避免因大型机械和繁琐工艺引起的安全隐患。…

MIT_线性代数笔记: 复习一

目录 问题一问题二问题三问题四 本讲为考前复习课&#xff0c;考试范围就是 Axb 这个单元&#xff0c;重点是长方形矩阵&#xff0c;与此相关的概念包括零空间、左零空间、秩、向量空间、子空间&#xff0c;特别是四个基本子空间。当矩阵为可逆的方阵时&#xff0c;很多性质是一…

二叉树的层次遍历

102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 样例输入 示例 1&#xff1a; 输入&#xff1a;root [3…

harmony开发之Text组件的使用

TextInput、TextArea是输入框组件&#xff0c;通常用于响应用户的输入操作&#xff0c;比如评论区的输入、聊天框的输入、表格的输入等&#xff0c;也可以结合其它组件构建功能页面&#xff0c;例如登录注册页面。 图片来源黑马程序员 Text组件的使用&#xff1a; 文本显示组…