【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前后台异 ...
随机推荐
- ou've likely run out of ephemeral ports on your system
redis.exceptions.ConnectionError: Error 99 connecting to 127.0.0.1:6379. Cannot assign requested add ...
- DBENV->open
https://stuff.mit.edu/afs/sipb/project/sandbox/golem/db-3.0.55/docs/api_c/env_open.html #include < ...
- Deep Learning 28:读论文“Multi Column Deep Neural Network for Traffic Sign Classification”-------MCDNN 简单理解
读这篇论文“ Multi Column Deep Neural Network for Traffic Sign Classification”是为了更加理解,论文“Multi-column Deep ...
- [10.26_P2] 最短路 (单源最短路应用)
单源最短路问题拓展 Description 给你一张图,图上有 n 个点,m 条边,要你找到两个点,使其最短路恰好包含给定的 k 个点.输出这条最短路的长度,输入保证有解. 输入格式 第一行两个数 n ...
- HDU1074 Doing Homework —— 状压DP
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Time Limit: 2000/1000 MS (J ...
- 超线程技术——超线程技术让(P4)处理器增加5%的裸晶面积,就可以换来15%~30%的效能提升,本质单核模拟双核!和异步编程的思想无异。
超线程是Intel 所研发的一种技术,于2002年发布.超线程的英文是HT技术,全名为Hyper-Threading,中文又名超线程.超线程技术原先只应用于Intel Xeon处理器中,当时称为Sup ...
- 一.OC基础之:1,OC语言的前世今生 ,2,OC语言入门,3,OC语言与C的差异,4,面向对象,5,类和对象的抽象关系,6,类的代码创建,7,类的成员组成及访问
1,OC语言的前世今生 , 一, 在20世纪80年代早期,布莱德.麦克(Brad Cox)设计了OC语言,它在C语言的基础上增加了一层,这意味着对C进行了扩展,从而创造出一门新的程序设计语言,支持对象 ...
- bzoj 3714 [ PA 2014 ] Kuglarz —— 思路+最小生成树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3714 因为每个杯子下最多一个小球,所以从奇偶性就可以看出有没有球: 询问一段区间,等于知道一 ...
- robotframework执行用例时,报错selenium.common.exceptions.WebDriverException: Message: unknown error: cannot get automation extension from unknown error: page could not be found: chrome-extension://aapnijgdinl
在用robotframework编写移动端测试用例(用chrome浏览器模拟手机浏览器),执行用例时, 报错selenium.common.exceptions.WebDriverException: ...
- log4j的1.2.15版本,在pom.xml中的顶层project报错错误: Failure to transfer javax.jms:jms:jar:1.1 from https://maven-repository.dev.java.net/nonav/repository......
在动态网站工程中,添加了Pom依赖,当添加log4j的1.2.15版本依赖时,在pom.xml中的顶层project报错错误: Failure to transfer javax.jms:jms:ja ...