【C++】异常简述(二):C++的异常处理机制
上文简述了在C语言中异常的处理机制,本文主要讲解C++中的异常处理.
一、异常的语法格式
在C++中,异常的抛出和处理主要使用了以下三个关键字:try、 throw 、 catch.其格式如下:
当我们在程序中想抛出一个异常时,可以这样:
#include<iostream>
#include<exception>
using namespace std;
int Div(int left,int right){
if(right==0){
throw exception("除数不能为0");
}
return left/right;
}
当我们想使用这个函数时,需要在函数外部进行异常的捕获:
int main(){
try{
Div(10,20); //合法
Div(10,30); //合法
Div(10,0); //非法,会抛出异常
}catch(exception & e){
e.what(); //打印异常信息
}
return 0;
}
如果存在不同类型的异常,我们可以这样:
try{
//包含可能抛出异常的语句;
}catch(类型名 [形参名]){
//可能出现的异常1
}catch(类型名 [形参名]){
//可能出现的异常2
}catch(...){
//如果不确定异常类型,在这里可以捕获所有类型异常!
}
二、异常抛出与捕获
1.异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪部分代码.
就上述代码来说,我们throw了一个exception对象,因此在捕获异常时,最终会匹配到catch到exception的代码块.
2.被选中的处理代码是调用链中与该对象类型匹配且离抛出位置最近的那个.
当try内的代码块出现异常时,系统会根据catch的顺序和参数的匹配程度来选择执行哪个代码块,因此,系统会选择最靠前且参数越匹配的代码块.
3. 抛出异常后会释放局部存储对象,所以被抛出的对象也就还给系统了,throw表达式会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,异常对象在传给对应的catch处理之后撤销。
也就是说,在上述的除法代码中,我们throw出的对象在抛出异常后会还给操作系统,而throw表达式会自己初始化一个匿名的对象副本,在传给catch相应的代码块后被回收.
三、栈展开
当我们的程序抛出异常时,会先暂停当前函数的执行,开始查找对应匹配的catch语句.
首先会检查throw是否在代码块内部.
如果是的话,再去找匹配的catch子句.
如果有匹配的,则进行处理.
如果没有,则退出当前函数栈,继续在调用函数的栈中进行从查找.
不断重复上述过程.
如果到达main函数栈,依旧没有匹配,则直接终止程序.
上述沿着调用链查找匹配的catch子句的过程称之为栈展开.
找到匹配的catch子句并处理以后,会继续沿着catch子句后面继续执行.
四、异常捕获的匹配规则
异常对象类型与catch说明符的类型必须完全匹配,只有以下几种情况例外:
1.允许从非const对象到const类型对象的转换.
2.允许派生类型到基类类型的转换.
3.将数组转换为指向数组类型的指针,将函数转换为指向函数的指针.
五、异常规范
在函数声明之后,列出该函数可能抛出异常类型,并保证该函数不会抛出其他类型的异常.
1、成员函数在类内声明和类外定义两处必须有相同的异常规范.
2、函数抛出一个没有被列在它异常规范中的异常时(且函数中抛出异常没有在函数内部进行处理),系统调用C++标准库中定义的函数unexpected().
3、如果异常规范为throw(),则表示不得抛出任何异常,该函数不用放在try块中.
4、派生类的虚函数的异常规范必须与基类虚函数的异常规范一样或更严格(是基类虚函数的异常的子集).
(因为派生类的虚函数被指向基类类型的指针调用时,保证不会违背基类成员函数的异常规范.)
六、异常与构造&析构函数
1. 构造函数完成对象的构造和初始化,需要保证不要在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化.
2. 析构函数主要完成资源的清理,需要保证不要在析构函数内抛出异常,否则可能导致资源泄漏(内存泄漏、句柄未关闭等).
七、自定义异常类型
自定义异常类型代码:
class Exception : public exception{
public:
Exception(int errId = 0,const char* errMsg = "")
:_errId(errId)
,_errMsg(errMsg){}
public:
virtual const char* what()const{
cout<<"errId:"<<_errId<<endl;
cout<<"errMsg:"<<_errMsg.c_str()<<endl;
return _errMsg.c_str();
}
private:
int _errId;
string _errMsg;
}
测试代码:
void TestException(){
throw Exception(1,"错误!");
}
int main(){
try{
TestException();
}catch(exception &e){
e.what();
}
}
关于C++异常处理这一块的知识暂时先整理到这里,感谢各位读者支持!
【C++】异常简述(二):C++的异常处理机制的更多相关文章
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...
- 分享知识-快乐自己:Spring中的(三种)异常处理机制
案例目录结构: Web.xml 配置: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application ...
- 【C++】异常简述(一):C语言中的异常处理机制
人的一生会遇到很多大起大落,尤其是程序员. 程序员写好的程序,论其消亡形式无非三种:无疾而终.自杀.他杀. 当然作为一名程序员,最乐意看到自己写的程序能够无疾而终,因此尽快的学习异常处理机制是非常重要 ...
- Java异常处理机制及两种异常的区别
java异常处理机制主要依赖于try,catch,finally,throw,throws五个关键字. try 关键字后紧跟一个花括号括起来的代码块,简称try块.同理:下面的也被称为相应的块. ...
- 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)
在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...
- Java -- 异常的捕获及处理 -- Java的异常处理机制
7.1.4 Java的异常处理机制 在整个Java的异常处理中,实际上也是按照面向对象的方式进行处理,处理的步骤如下: ⑴ : 一旦产生异常,则首先会产生一个异常类的实例化对象. ⑵ : 在try语句 ...
- Atititjs javascript异常处理机制与java异常的转换.js exception process
Atititjs javascript异常处理机制与java异常的转换.js exception process 1. javascript异常处理机制 Throw str Not throw err ...
- Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception process Vob7
Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception processVob7 1. 1. javascript异常处理机制 ...
- Atitit.js javascript异常处理机制与java异常的转换.js exception process Voae
Atitit.js javascript异常处理机制与java异常的转换.js exception processVoae 1. 1. javascript异常处理机制 1 2. 2. Web前后台异 ...
随机推荐
- GridView根据一列自动计算(转载)
<%@ Page Language="C#" %> <%@ Import Namespace="System.Xml" %> <! ...
- 2016/05/15 ThinkPHP3.2.2 表单自动验证实例 验证规则的数组 直接写在相应的控制器里
使用TP 3.2框架 验证规则也可以写到模型里,但感觉有些麻烦, 一是有时候不同页面验证的方式会不一样, 二是看到这个 Add 事件里的代码,就清楚要接收什么数据,如何验证数据能够在第一眼有个大 ...
- 2016/2/29 html 思维导图
- 从远程Linux Copy文件到本机 界面化操作
1.安装SSHSecureShellClient 2.打开 3.设置1,然后打开2就可以操作了
- CodeForces-204E:Little Elephant and Strings (广义后缀自动机求出现次数)
The Little Elephant loves strings very much. He has an array a from n strings, consisting of lowerca ...
- BZOJ_1307_玩具_单调栈+双指针
BZOJ_1307_玩具_单调栈+双指针 Description 小球球是个可爱的孩子,他喜欢玩具,另外小球球有个大大的柜子,里面放满了玩具,由于柜子太高了,每天小球球都会让妈妈从柜子上拿一些玩具放在 ...
- bzoj1296 [SCOI2009]粉刷匠——背包
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1296 对于不同木板之间,最终统计答案时做一个分组背包即可: 而要进行分组背包,就需要知道每个 ...
- SimpliciTI协议栈
SimpliciTI组网过程介绍 1.SimpliciTI支持点对点和星形的网络拓扑结构. 下面介绍以AP为中心的SimpliciTI网路协议的星形拓扑结构通信过程 1)当ED节点上电之后就扫描信 ...
- JSP 注释的详解及简单实例
转自:https://www.jb51.net/article/124727.htm JSP 注释的详解及简单实例 一 三种格式 二 举例 ? 1 2 3 4 5 6 7 8 9 10 11 12 1 ...
- IEEE Trans 2006 使用K-SVD构造超完备字典以进行稀疏表示(稀疏分解)
K-SVD可以看做K-means的一种泛化形式,K-means算法总每个信号量只能用一个原子来近似表示,而K-SVD中每个信号是用多个原子的线性组合来表示的. K-SVD算法总体来说可以分成两步 ...