为“异常”努力是值得的

异常是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++>>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MOS管防护电路解析

功率MOS管自身拥有众多优点&#xff0c;但是MOS管具有较脆弱的承受短时过载能力&#xff0c;特别是在高频的应用场合&#xff0c;所以在应用功率MOS管对必须为其设计合理的保护电路来提高器件的可靠性。 功率MOS管保护电路主要有以下几个方面&#xff1a; 1&#xff09;防止栅…

苹果 macOS 14.1.2 正式发布 更新了哪些内容?

苹果今日向 Mac 电脑用户推送了 macOS 14.1.2 更新&#xff08;内部版本号&#xff1a;23B92 | 23B2091&#xff09;&#xff0c;本次更新距离上次发布隔了 28 天。 需要注意的是&#xff0c;因苹果各区域节点服务器配置缓存问题&#xff0c;可能有些地方探测到升级更新的时间略…

销售技巧培训之女装销售技巧

销售技巧培训之女装销售技巧 一、了解目标客户 在销售女装时&#xff0c;了解目标客户是非常重要的。不同年龄段、不同职业、不同收入的女性对女装的需求和偏好都不同。因此&#xff0c;在销售女装时&#xff0c;需要先了解目标客户的特点和需求&#xff0c;以便更好地推荐适…

《opencv实用探索·十四》VideoCapture播放视频和视像头调用

1、VideoCapture播放视频 #include <opencv2/opencv.hpp> #include <iostream>using namespace std; using namespace cv;int main() {// 定义相关VideoCapture对象VideoCapture capture;// 打开视频文件capture.open("1.avi");// 判断视频流读取是否正…

OpenCL学习笔记(一)开发环境搭建(win10+vs2019)

前言 异构编程开发&#xff0c;在高性能编程中有重要的&#xff0c;笔者本次只简单介绍下&#xff0c;如何搭建简单的开发环境&#xff0c;可以供有需要的小伙伴们开发测试使用 一、获取opencl的sdk库 1.使用cuda库 若本机有Nvidia的显卡&#xff0c;在安装cuda库后&#x…

spring boot学习第五篇:spring boot与JPA结合

1、准备表&#xff0c;创建表语句如下 CREATE TABLE girl (id int(11) NOT NULL AUTO_INCREMENT,cup_Size varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,age int(11) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT4 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4…

《ReactJS实践入门》:引领JavaScript前端开发的革新之旅

在当今的软件开发世界中&#xff0c;ReactJS无疑是最为引人注目的JavaScript库之一。对于初学者来说&#xff0c;如何深入理解并掌握这一强大的前端工具&#xff0c;进而应用到实际开发中&#xff0c;一直是他们所面临的问题。而《ReactJS实践入门》一书&#xff0c;正是为了解…

西部再添“芯”增长极 | 海辰储能重庆基地正式投产

12月7日&#xff0c;海辰储能重庆基地一期一阶段项目投产仪式在重庆铜梁举行。此次重庆基地项目的投产&#xff0c;是海辰储能实施三大基地协同发展战略的重要里程碑&#xff0c;将进一步整合内部资源、发挥规模化生产优势、完善产业链布局&#xff0c;成为海辰储能持续迈向高质…

第二十一章

这一章 基本分为三个部分 网络基础概念和TCP,UDP这三个部分主要如下&#xff1a; 计算机网络实现了堕胎计算机间的互联&#xff0c;使得它们彼此之间能够进行数据交流。网络应用程序就是再已连接的不同计算机上运行的程序&#xff0c;这些程序借助于网络协议&#xff0c;相互…

如何切换用户和更改用户密码

https://blog.csdn.net/u012759006/article/details/89681615 https://blog.csdn.net/Z_CAIGOU/article/details/120925716 1、sudo su 切换到root用户 2、passwd 用户名 之后输入你修改后的密码两次&#xff0c;成功。 文章知识点与官方知识档案匹配&#xff0c;可 一般情…

DDD架构思想专栏一《初识领域驱动设计DDD落地》

引言 最近准备给自己之前写的项目做重构&#xff0c;这是一个单体架构的小项目&#xff0c;后端采用的是最常见的三层架构。因为项目比较简单&#xff0c;其实采用三层架构就完全够了。但是呢&#xff0c;小编最近在做DDD架构的项目&#xff0c;于是就先拿之前写的一个老项目试…

【ET8】1.ET8入门-运行指南

主要学习网址 论坛地址为&#xff1a;https://et-framework.cn Git地址为&#xff1a;GitHub - egametang/ET: Unity3D Client And C# Server Framework 官方QQ群 : 474643097 项目检出 检出项目切换到release8.0分支 GitHub地址&#xff1a;GitHub - egametang/ET: Unity…

2023-12-08面试

1、自我介绍 面试官你好&#xff0c;我叫平明博&#xff0c;来自河南郑州&#xff0c;19年毕业&#xff0c;所学专业软件工程&#xff0c;之前任职于南京华苏科技&#xff0c;担任开发工程师一职&#xff0c;在职期间主要对省间现货相关项目进行研发&#xff0c;核心就是从多平…

nvidia安装出现7-zip crc error解决办法

解决办法&#xff1a;下载network版本&#xff0c;重新安装。&#xff08;选择自己需要的版本&#xff09; 网址&#xff1a;CUDA Toolkit 12.3 Update 1 Downloads | NVIDIA Developer 分析原因&#xff1a;local版本的安装包可能在下载过程中出现损坏。 本人尝试过全网说的…

crmeb本地开发配置代理

crmeb 是一个开源的商城系统&#xff0c; v5 版本是一个前后端分离的项目&#xff0c; 我们从git仓库中下载下来的是一个文件夹&#xff0c;其结构是这样的 我的系统没有使用docker &#xff0c;使用的是 laragon 的系统 所以首先我们要在 nginx 中配置 之后&#xff0c; 我们…

钒电解液回收提钒树脂

#钒电解液回收提钒树脂 钒是一种重要的战略金属具有硬度大、抗拉强度强、熔点高等优点主要应用于冶金、电池、核材料、航空航天及能源等领域。 钒电池全称全钒氧化还原液流电池具有环境友好、循环寿命长、能量效率较高等优点&#xff0c;钒电解液是钒电池的关键部分由钒离子和硫…

阿里云国际基于CentOS系统镜像快速部署Apache服务

阿里云轻量应用服务器提供了Windows Server系统镜像和主流的Linux系统镜像&#xff0c;您可以通过该类镜像创建纯净、安全、稳定的运行环境。本文以CentOS 7.6系统镜像为例&#xff0c;介绍如何快速配置Apache服务。 背景信息 注意&#xff0c;阿里云国际通过corebyt注册并充…

【小白专用】MySQL入门(详细总结)

3. 创建数据库 使用 create database 数据库名; 创建数据库。 create database MyDB_one; create database DBAliTest; 创建数据库成功后&#xff0c;数据库的数量变成了6个&#xff0c;多了刚才创建的 dbalitest 。 4. 创建数据库时设置字符编码 使用 create database 数据…

(六) python观察者设计模式

6.1行为型模式简介 观察者设计模式是最简单的行为型模式之一,所以我们先简单了解一下行为型模式 创建型模式的工作原理是基于对象的创建机制的。由于这些模式隔离了对象的创建细 节&#xff0c;所以使得代码能够与要创建的对象的类型相互独立。结构型模式用于设计对象和类的结…

echarts折线图的数据显示

一、 echarts让折线图的每个折点都显示y轴的数值 效果如下 // 在 series中添加 itemStyle : { normal: {label : {show: true}}}series: [{name: 买入汇率,data: BuyRate,type: line,itemStyle : { normal: {label : {show: true}}}},{name: 卖出汇率,data: SaleRate,type: lin…