【C++11】异常处理

news2024/9/23 5:22:15

目录

一、异常的引入

二、C++异常的关键字

三、异常的抛出与处理规则

四、异常缺陷的处理

五、自定义异常体系

六、异常规范

七、异常安全

八、异常的优缺点

1.优点

2.缺点


一、异常的引入

传统的C语言处理异常的方式有两种:
1.终止程序:使用assert断言语句,如果发生内存错误等,比如内存泄漏或者除0错误,都会直接终止程序。
2.返回错误码:通过错误码判断发生的异常的类型是什么,如系统的很多库的接口程序通过把错误码放到errno中,表示错误。
在实际中的C语言程序基本都是通过返回错误码的方式来处理错误的,部分情况下使用终止程序来处理比较严重的错误。

二、C++异常的关键字

目前市面上的大部分的主流语言都是使用异常机制来处理错误的,当一个函数发现自己无法处理一些错误的时候会进行抛异常处理,让函数直接跳转到捕获异常的地方去处理异常。

下面介绍C++处理异常的几个关键字:

1.throw:当问题出现的时候,程序会抛出一个异常,这是通过throw关键字来完成的。

2.catch:通过异常处捕获异常,catch块主要用于处理异常,或者执行一些其他的操作。

3.try:try块中的代码标识将被激活的特定异常,它的后面一般会跟一个catch块。

三、异常的抛出与处理规则

double Exception(int n1, int n2)
{
	if (n2 == 0)
	{
		throw "Devision by zero condition";
	}
	else
	{
		return ((double)n1 / (double)n2);
	}
}
void func()
{
	int n1, n2;
	cin >> n1 >> n2;
	cout << Exception(n1, n2) << endl;
}
int main()
{
	try
	{
		func();
	}
	catch (const char* errmsg)
	{
		cout << "Devision by zero condition" << endl;
	}
	catch (...)
	{
		cout << "未知异常" << endl;
	}
	return 0;
}

当向n2传入的值为0的时候,调用throw抛出异常,catch会捕获该异常进行处理。

  • 1.异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪一个catch的处理代码。
  • 2.被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的一个。
    在这段程序中,有一个调用链:main()->Func()->Disvision(),在Disvision中抛出异常就会沿着调用链寻找能捕获异常的catch来执行。假设Func()中有一个与main()中一模一样的catch函数,那么除0的异常就会优先调用Func()中的catch,因为它离着最近。

  • 3.catch的异常其实是抛出对象的拷贝,因为真正抛出的对象在出作用域的时候就已经被销毁了,拷贝的对象在catch成功之后也会自动销毁。

  • 4.catch(…)可以捕获任意类型的异常,但问题是不知道异常错误是什么。
  • 5.实际中抛出和捕获的匹配原则有一个例外,并不都是类型完全匹配,可以抛出的派生类对象,使用基类捕获。(要引入多态)
  • 6.当catch异常之后,会沿着catch后的子句继续执行。

四、异常缺陷的处理

double Exception(int n1, int n2)
{
	if (n2 == 0)
	{
		throw "Devision by zero condition";
	}
	else
	{
		return ((double)n1 / (double)n2);
	}
}
void func()
{
	int* array = new int[10];
	int n1, n2;
	cin >> n1 >> n2;
	cout << Exception(n1, n2) << endl;
	delete[] array;//一旦抛出异常,这里就不会被执行
}
int main()
{
	try
	{
		func();
	}
	catch (const char* errmsg)
	{
		cout << errmsg << endl;
	}
	catch (...)
	{
		cout << "未知异常" << endl;
	}
	return 0;
}

对于这段代码而言,一旦Exception抛出异常就会立刻执行主函数中的catch,delete释放内存就不会被执行。因此我们需要对这种情况进行处理,即在Func中也捕获一次异常,但是不对异常进行处理,只是释放空间:

void func()
{
	int* array = new int[10];
	int n1, n2;
	cin >> n1 >> n2;
	try
	{
		cout << Exception(n1, n2) << endl;
	}
	catch (...)
	{
		cout << "释放空间" << endl;
		delete[] array;
		throw;
	}
}

在释放空间之后,直接调用throw,"..."是任何异常都接收,只有"throw"表示将捕获到的异常再跑出去。

五、自定义异常体系

六、异常规范

1.异常规格说明的目的是让函数使用者知道,可以在函数的后面接throw类(类型),列出这个函数可能抛出的所有异常。

2.函数后面接throw(),表示函数不抛异常。

3.若无异常接口声明,则此函数可以抛掷任何类型的异常。

void func() throw(A, B, C, D);//只会抛A/B/C/D中的某中类型的异常
void* operator new(size_t size)throw(bad alloc);//这里表示这个函数只会抛出bad_alloc这种异常
void* operator new(size_t size, void* ptr) throw();这个函数不会抛异常

在C++中,引入了noexception

bool exception(int x, int y) noexcept(noexcept(x > y))
{
	return x > y;//表示如果x>y不发生异常,则Compare函数不会发生异常。
}

七、异常安全

构造函数完成对象的初始化,最好不要在构造函数中抛异常,否则可能导致对象不完整,或没有完全初始化。

析构函数主要完成资源的清理,最好不要在析构函数中抛异常,否则可能导致资源泄露。

C++异常经常会导致资源泄露的问题,比如在new和delete中抛异常,导致内存泄漏,在lock和unlock之间抛出了异常导致死锁,C++经常使用RAll来解决以上问题,关于RAll我们在智能指针中讲解。

八、异常的优缺点

1.优点

1.相比错误码,更加清晰展示出错信息。

2.很多库中包含异常,boost,gtest,gmock等常用的库,使用它们也需要异常。

3.部分函数使用异常更好处理,比如构造函数没有返回值,不方便使用错误码方式处理,比如T&operator[]这样的函数,只有一个返回值,如果pos越界了只能使用异常或者终止程序处理,没办法通过返回值表示错误。

2.缺点

1.异常类似goto,会导致程序的执行流乱跳,并且非常混乱。

2.C++没有垃圾回收机制,可能导致内存泄漏。

3.各个公司的异常体系不同,有一定的学习成本。

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

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

相关文章

[WMCTF2020]Make PHP Great Again 2.01

又是php代码审计,开始吧. 这不用审吧&#xff0c;啊喂. 意思就是我们要利用require_once()函数和传入的file的value去读取flag的内容.&#xff0c;貌似呢require_once()已经被用过一次了&#xff0c;直接读取还不行&#xff0c;看一下下面的知识点. require_once() require…

Qt 注册表操作

一.操作环境 二.注册表查看 1. 搜索注册表打开 2. 注册表查看 例如我想操作 计算机\HKEY_CURRENT_USER\SOFTWARE\winzq\qwert下的内容 三.代码 1. H文件 #ifndef __REGISTER_H__ #define __REGISTER_H__#include <QString> #include <QSettings> #include <Q…

Web 安全(Web Security)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

信息安全工程师(11)网络信息安全科技信息获取

一、信息获取的重要性 在网络安全领域&#xff0c;及时、准确地获取科技信息对于防范和应对网络威胁至关重要。这些信息可以帮助安全团队了解最新的攻击手段、漏洞信息、防护技术等&#xff0c;从而制定有效的安全策略和应对措施。 二、信息获取的来源 网络信息安全科技信息的获…

s3c2440各部分应用

一、按位运算 按位与&&#xff1a;清零&#xff0c;清零位&0&#xff1b; 如&#xff1a;0xFFFF &&#xff08; ~&#xff08;1 << 7&#xff09;&#xff09;, 将第7位清零。 按位或 | &#xff1a;置1&#xff0c;置1位 | 1&#xff1b; 如&…

MySQL(七)——事务

文章目录 事务事务的概念事务的ACID特性事务的语法查看存储引擎查看自动提交参数和设置手动事务操作保存点 隔离级别与并发事务问题隔离级别并发事务问题 事务 事务的概念 事务&#xff08;Transaction&#xff09;是数据库管理系统中执行过程中的一个逻辑单位&#xff0c;由…

Rx Strategist:智能体实现处方验证的方方面面,如适应症、剂量、药物相互作用

Rx Strategist&#xff1a;智能体实现处方验证的方方面面&#xff0c;如适应症、剂量、药物相互作用 秒懂大纲提出背景&#xff1a;拆解解法分析全流程分析创意 秒懂大纲 ├── 处方验证系统【主题】 │ ├── 背景和问题【问题描述】 │ │ ├── 现代药物复杂性对严…

Java基础面试题——异常

目录 关系图 1. Throwable和Exception之间的关系 2.异常分为哪两大类 3.常见的 RuntimeException 4. 常见的 Error 5.什么是已检查异常和未检查异常&#xff1f;它们的区别是什么&#xff1f; 6.Java 中如何自定义异常&#xff1f; 7.throw 和 throws 的区别是什么&…

ML 系列:机器学习和深度学习的深层次总结(07)数据预处理—解决缺失值、异常值和错误数据

文章目录 一、说明二、数据预处理三、缺失值四、数据集中可能会出现多种类型的缺失值&#xff1a;五、处理缺失值的方法六、结论 一、说明 在AI数据挖掘中&#xff0c;对原始数据的预处理是必须的技术手段&#xff0c;本篇将对数据预处理的一系列注意事项进行展示。 二、数据…

JavaEE: 深入探索TCP网络编程的奇妙世界(五)

文章目录 TCP核心机制TCP核心机制六: 拥塞控制为什么要有拥塞控制?动态调整的拥塞控制拥塞控制中,窗口大小具体的变化过程 TCP核心机制七: 延时应答TCP核心机制八: 捎带应答 TCP核心机制 前一篇文章 JavaEE: 深入探索TCP网络编程的奇妙世界(四) 书接上文~ TCP核心机制六: 拥…

数据结构:二叉树OJ题(基础版)

前言 更完两期二叉树的知识之后&#xff0c;来做几道oj题巩固一下基础 一、翻转二叉树 链接&#xff1a;leetcode链接 还是分治思想&#xff0c;将问题分解成左子树和右子树交换&#xff0c;遇到空树停止 采用递归算法做题 TreeNode* invertTree(TreeNode* root) {if(root …

2D目标检测常用loss

在2D目标检测任务中&#xff0c;常用的损失函数&#xff08;Loss&#xff09;主要用于优化以下三个关键方面&#xff1a; 类别分类&#xff08;Classification&#xff09;&#xff1a;用于区分检测到的对象属于哪一类。边界框回归&#xff08;Bounding Box Regression&#x…

Spring Boot蜗牛兼职网:全栈开发

第4章 系统设计 4.1 系统体系结构 蜗牛兼职网的结构图4-1所示&#xff1a; 图4-1 系统结构 登录系统结构图&#xff0c;如图4-2所示&#xff1a; 图4-2 登录结构图 蜗牛兼职网结构图&#xff0c;如图4-3所示。 图4-3 蜗牛兼职网结构图 4.2开发流程设计 系统流程的分析是通…

在Web开发中使用和风天气接口

介绍 和风天气是一个提供全球天气预报和气象数据的服务平台&#xff0c;支持多种语言&#xff0c;提供实时天气、未来天气预报、空气质量指数、生活建议等多种气象数据&#xff0c;可以广泛用于网页开发、移动应用和物联网设备等场景。 开发文档&#xff1a;文档 | 和风天气开…

intellij idea 控制台运行java出现中文乱码的解决方法

原因&#xff1a; 字符编码不一致&#xff1a; 当你在intellij idea使用了UTF-8编码&#xff0c;而在控制台使用了其他编码&#xff08;比如gbk&#xff09;&#xff0c;就可能导致乱码。 文件读写编码问题&#xff1a; 如果读取文件时使用的编码与文件实际编码不一致&#xf…

Chainlit集成LlamaIndex实现知识库高级检索(自动合并检索)

检索原理 自动合并检索 自动合并检索原理&#xff0c;和我的上一篇文章的检索方案&#xff1a; 将文本分割成512大小&#xff08;一般对应段落大小&#xff09;和128&#xff08;一般对句子大小不是严格的句子长度&#xff09;大小两种分别存储到索引库&#xff0c;再用llama_…

《深度学习》—— 卷积神经网络(CNN)的简单介绍和工作原理

文章目录 一、卷积神经网络的简单介绍二、工作原理(还未写完)1.输入层2.卷积层3.池化层4.全连接层5.输出层 一、卷积神经网络的简单介绍 基本概念 定义&#xff1a;卷积神经网络是一种深度学习模型&#xff0c;通常用于图像、视频、语音等信号数据的分类和识别任务。其核心思想…

如何在Markdown写文章上传到wordpress保证图片不丢失

如何在Markdown写文章上传到wordpress保证图片不丢失 写文日期,2023-11-16 引文 众所周知markdown是一款nb的笔记软件&#xff0c;本篇文章讲解如何在markdown编写文件后上传至wordpress论坛。并且保证图片不丢失&#xff08;将图片上传至云端而非本地方法&#xff09; 一&…

通信工程学习:什么是NFVI网络功能虚拟化基础设施层

NFVI&#xff1a;网络功能虚拟化基础设施层 NFVI&#xff08;Network Functions Virtualization Infrastructure&#xff09;即网络功能虚拟化基础设施层&#xff0c;是NFV&#xff08;Network Functions Virtualization&#xff0c;网络功能虚拟化&#xff09;架构中的一个重要…

精准农业中遥感技术应用(五)- 一站式遥感数据服务平台AIEarth

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案&#xff0c;帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、领域知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&…