上文简述了在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++的异常处理机制的更多相关文章

  1. springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)

    上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...

  2. 分享知识-快乐自己:Spring中的(三种)异常处理机制

    案例目录结构: Web.xml 配置: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application ...

  3. 【C++】异常简述(一):C语言中的异常处理机制

    人的一生会遇到很多大起大落,尤其是程序员. 程序员写好的程序,论其消亡形式无非三种:无疾而终.自杀.他杀. 当然作为一名程序员,最乐意看到自己写的程序能够无疾而终,因此尽快的学习异常处理机制是非常重要 ...

  4. Java异常处理机制及两种异常的区别

    java异常处理机制主要依赖于try,catch,finally,throw,throws五个关键字.   try 关键字后紧跟一个花括号括起来的代码块,简称try块.同理:下面的也被称为相应的块. ...

  5. 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)

    在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...

  6. Java -- 异常的捕获及处理 -- Java的异常处理机制

    7.1.4 Java的异常处理机制 在整个Java的异常处理中,实际上也是按照面向对象的方式进行处理,处理的步骤如下: ⑴ : 一旦产生异常,则首先会产生一个异常类的实例化对象. ⑵ : 在try语句 ...

  7. Atititjs javascript异常处理机制与java异常的转换.js exception process

    Atititjs javascript异常处理机制与java异常的转换.js exception process 1. javascript异常处理机制 Throw str Not throw err ...

  8. Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception process Vob7

    Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception processVob7 1. 1. javascript异常处理机制 ...

  9. Atitit.js javascript异常处理机制与java异常的转换.js exception process Voae

    Atitit.js javascript异常处理机制与java异常的转换.js exception processVoae 1. 1. javascript异常处理机制 1 2. 2. Web前后台异 ...

随机推荐

  1. 正向代理tinyproxy使用总结

    使用tinyproxy的问题背景: 其实以前代理一直用的是apache,后来,那次有个任务要给ios的推送设置代理,任务很紧急,可是apache报错. 原因如下:APNS发送通知的端口2195,但是A ...

  2. 前端预览图片和H5canvas压缩图片上传

    思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法得到base64字符串来实现压缩. 1.base64转二进制文件 /** * dataURL to blob, re ...

  3. Lightoj 1016 - Brush (II)

    After the long contest, Samee returned home and got angry after seeing his room dusty. Who likes to ...

  4. ubuntu12.04安装tftp,配置,修改目录,错误类型

    [前言]学习嵌入式,需要配置tftp服务,在网上搜了搜,很多,但是配置了,我的老是出现Error code 1: File not found错误,经过探索和一个大哥的博客http://blog.cs ...

  5. 连通图(Tarjan算法) 专题总结

    一.题目类型: 1.有向图的强连通分量: POJ1236 Network of Schools HDU1269 迷宫城堡 2.割点 & 割边: UESTC - 900 方老师炸弹 UVA315 ...

  6. HDU1698 Just a Hook —— 线段树 区间染色

    题目链接:https://vjudge.net/problem/HDU-1698 In the game of DotA, Pudge’s meat hook is actually the most ...

  7. NSString字符串截取方法

    1.字符串 1> 字符串比较 NSString *a = @“hello”; NSString *b = [NSString stringWithFormat:@hello”]; if (a = ...

  8. Spring 各种注解(@)的含义与认识

    依赖注入,从字面上理解,即是:以注入的方式实现依赖: Spring 容器负责创建应用程序中的 bean,并通过 DI(依赖注入)来协调这些对象之间的关系.当描述 bean 如何进行装配(autowir ...

  9. hdu 1480

    钥匙计数之二 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  10. Image2Caption

    定义 图像标注或语言生成图像问题把计算机视觉与自然语言处理联系在了一起,是广义的人工智能领域的一大难题.通常涉及到特征提取(用cnn提取出图像内部不为人类感知的向量特征)和语言模型建立.为图像提取文字 ...