exceptionType是异常类型,它指明了当前的 catch 可以处理什么类型的异常;variable是一个变量,用来接收异常信息。当程序抛出异常时,会创建一份数据,这份数据包含了错误信息,程序员可以根据这些信息来判断到底出了什么问题,接下来怎么处理。

异常既然是一份数据,那么就应该有数据类型。C++ 规定,异常类型可以是 int、char、float、bool 等基本类型,也可以是指针、数组、字符串、结构体、类等聚合类型。C++ 语言本身以及标准库中的函数抛出的异常,都是 exception 类或其子类的异常。也就是说,抛出异常时,会创建一个 exception 类或其子类的对象。

exceptionType variable和函数的形参非常类似,当异常发生后,会将异常数据传递给 variable 这个变量,这和函数传参的过程类似。当然,只有跟 exceptionType 类型匹配的异常数据才会被传递给 variable,否则 catch 不会接收这份异常数据,也不会执行 catch 块中的语句。换句话说,catch 不会处理当前的异常。

我们可以将 catch 看做一个没有返回值的函数,当异常发生后 catch 会被调用,并且会接收实参(异常数据)

catch 和真正的函数调用的区别:

 真正的函数调用,形参和实参的类型必须要匹配,或者可以自动转换,否则在编译阶段就报错了。而对于 catch,异常是在运行阶段产生的,它可以是任何类型,没法提前预测,所以不能在编译阶段判断类型是否正确,只能等到程序运行后,真的抛出异常了,再将异常类型和 catch 能处理的类型进行匹配,匹配成功的话就“调用”当前的 catch,否则就忽略当前的 catch。

总起来说,catch 和真正的函数调用相比,多了一个「在运行阶段将实参和形参匹配」的过程。

另外需要注意的是,如果不希望 catch 处理异常数据,也可以将 variable 省略掉,也即写作:

try{// 可能抛出异常的语句
}catch(exceptionType){// 处理异常的语句
}

这样只会将异常类型和 catch 所能处理的类型进行匹配,不会传递异常数据了。

多级 catch

一个 try 对应一个 catch,这只是最简单的形式。其实,一个 try 后面可以跟多个 catch:

try{//可能抛出异常的语句
}catch (exception_type_1 e){//处理异常的语句
}catch (exception_type_2 e){//处理异常的语句
}
//其他的catch
catch (exception_type_n e){//处理异常的语句
}

当异常发生时,程序会按照从上到下的顺序,将异常类型和 catch 所能接收的类型逐个匹配。一旦找到类型匹配的 catch 就停止检索,并将异常交给当前的 catch 处理(其他的 catch 不会被执行)。如果最终也没有找到匹配的 catch,就只能交给系统处理,终止程序的运行。

多级 catch 的使用:

#include <iostream>
#include <string>
using namespace std;class Base{ };
class Derived: public Base{ };int main(){try{throw Derived();  //抛出自己的异常类型,实际上是创建一个Derived类型的匿名对象cout<<"This statement will not be executed."<<endl;}catch(int){cout<<"Exception type: int"<<endl;}catch(char *){cout<<"Exception type: cahr *"<<endl;}catch(Base){  //匹配成功(向上转型)cout<<"Exception type: Base"<<endl;}catch(Derived){cout<<"Exception type: Derived"<<endl;}return 0;
}

运行结果:

Exception type: Base

在 catch 中,我们只给出了异常类型,没有给出接收异常信息的变量。
本例中,我们定义了一个基类 Base,又从 Base 派生类出了 Derived。抛出异常时,我们创建了一个 Derived 类的匿名对象,也就是说,异常的类型是 Derived。

我们期望的是,异常被catch(Derived)捕获,但是从输出结果可以看出,异常提前被catch(Base)捕获了,这说明 catch 在匹配异常类型时发生了向上转型(Upcasting)。

catch 在匹配过程中的类型转换

C/C++ 中存在多种多样的类型转换,以普通函数(非模板函数)为例,发生函数调用时,如果实参和形参的类型不是严格匹配,那么会将实参的类型进行适当的转换,以适应形参的类型,这些转换包括:

算数转换:例如 int 转换为 float,char 转换为 int,double 转换为 int 等。

向上转型:也就是派生类向基类的转换。

const 转换:也即将非 const 类型转换为 const 类型,例如将 char * 转换为 const char *。

数组或函数指针转换:如果函数形参不是引用类型,那么数组名会转换为数组指针,函数名也会转换为函数指针。

用户自定的类型转换

catch 在匹配异常类型的过程中,也会进行类型转换,但是这种转换受到了更多的限制,仅能进行「向上转型」、「const 转换」和「数组或函数指针转换」,其他的都不能应用于 catch。

const 转换以及数组和指针的转换:

#include <iostream>
using namespace std;int main(){int nums[] = {1, 2, 3};try{throw nums;cout<<"This statement will not be executed."<<endl;}catch(const int *){cout<<"Exception type: const int *"<<endl;}return 0;
}

运行结果:

Exception type: const int *

nums 本来的类型是int [3],但是 catch 中没有严格匹配的类型,所以先转换为int *,再转换为const int *。

C++ 异常类型以及多级catch匹配相关推荐

  1. java判捕获e异常类型_Java SE7新特性之捕获多种类型的异常并且重新抛出使用改进的类型检查的异常...

    本文涵盖了以下主题: 处理多种类型的异常 重新抛出使用更宽泛的类型检查的异常 在Java SE 7 以及后续版本中, 一个简单的 catch 块可以处理多种类型的异常.这种特性可以减少重复代码以及对于 ...

  2. Java异常之try,catch,finally,throw,throws

    Java异常之try,catch,finally,throw,throws 你能区分异常和错误吗? 我们每天上班,正常情况下可能30分钟就能到达.但是由于车多,人多,道路拥挤,致使我们要花费更多地时间 ...

  3. 异常行为检测算法_检测异常行为的异常或异常类型算法

    异常行为检测算法 Anomaly detection is a critical problem that has been researched within diverse research ar ...

  4. Java中的异常总结详解(异常类型、声明异常、抛出异常、捕获异常)

    Java 异常解析 前言 一.异常概述 二.异常类型 1.系统错误(Error) 2.编译时异常(Exception) 3.运行时异常(RuntimeException) 三.处理编译时异常的更多知识 ...

  5. 前端魔法堂——异常不仅仅是try/catch

    前言  编程时我们往往拿到的是业务流程正确的业务说明文档或规范,但实际开发中却布满荆棘和例外情况,而这些例外中包含业务用例的例外,也包含技术上的例外.对于业务用例的例外我们别无它法,必须要求实施人员与 ...

  6. java异常类型和基本处理原则_Java异常控制机制和异常处理原则

    Java异常控制机制又被称为"违例控制机制". 捕获程序错误最理想的时机是在编译阶段,这样可以彻底避免错误的代码运行.但并非所有的错误都能在编译期间侦测到,有些问题必须在运行期间解 ...

  7. php 该throw还是该404,前端魔法堂——异常不仅仅是try/catch

    前言 编程时我们往往拿到的是业务流程正确的业务说明文档或规范,但实际开发中却布满荆棘和例外情况,而这些例外中包含业务用例的例外,也包含技术上的例外.对于业务用例的例外我们别无它法,必须要求实施人员与用 ...

  8. 常见的几种异常类型 Exception

    常见异常类型: Java中的异常分为两大类: 1.Checked Exception(非Runtime Exception) 2.Unchecked Exception(Runtime Excepti ...

  9. java异常类型 数组越界_java数组中的异常类型整理

    对于程序中出现异常,是很多程序员不想看到的情况,因为这就需要我们去查询异常的原因,然后进行一些处理异常的操作.在Java数组操作时,也会有一些异常情况的发生.这里我们罗列出了两种:ClassCastE ...

最新文章

  1. matlab 寻找二进制图像边缘
  2. java 四种实现延迟加载的方法
  3. 大数据告诉你,电商都把假货发给谁?
  4. 【HDU - 3068】最长回文(Manacher算法,马拉车算法求最长回文子串)
  5. java浮点型需知_java使用数字类型注意事项
  6. 使用PDO连接数据库 查询和插入乱码的解决方法
  7. 力扣226-翻转二叉树(C++,附思路)
  8. flv 开源 修复_如何修复开源软件中的错误
  9. flask创建mysql表_Flask-SQLAlchemy 无法创建数据库???
  10. 这样讲 Netty 中的心跳机制,还有谁不会?
  11. CVPR2019,开源活体检测
  12. Java中Link,set 和Map的区别,ArrayList,HashSet和HashMap的区别。
  13. Atitit. Dwr 抛出异常error解决方案
  14. 多个折线样式_Python数据可视化实例:关于图表“贵族”折线的增强优化方法
  15. word 单独设置正文页码
  16. A Piece of ODE
  17. 机器学习--KNN算法应用,iris鸢尾花数据集的分类
  18. RUOYI 框架教程 1 |小白都能学会的 3 分钟搭建框架教程
  19. python %d, %f, %s占位符的使用(学习笔记)
  20. CISCO MFC中部署Firepower FTD高可用(HA)---By 年糕泰迪

热门文章

  1. python中input函数的返回是哪种类型_Python3.x中input的变化:input函数默认返回字符串类型...
  2. gerber文件怎么导贴片坐标_SMT贴片机在线编程调试
  3. oracle conneciton properties,在WAS Liberty连接池中,我可以验证借用连接吗?
  4. php ajax json 实例,php+ajax+json 详解及实例代码
  5. beego 例子_beego框架代码分析
  6. 在java中的交换方法有哪些_java中交换两个变量的值有哪几种方法,交换两个变量a和b的值...
  7. c语言 %15s,c语言求助
  8. java gc时会暂停运行吗,java gc 项目终止运行
  9. SpringBoot 使用AOP功能
  10. 编写并调试一个单道处理系统的作业调度模拟程序_操作系统系列(2):操作系统发展历史...