- 异常是程序运行中出现的不正常情况。
- 健壮性是在异常情况下系统生存的关键所在,计算机程序在输入错误、磁盘故障、网络过载或恶意攻击的情况下能否不死机、不崩溃,就是程序的健壮性。
1 异常分类
CPU异常
- 在计算过程中,出现除数为0的情况的不正常现象。
内存异常
- 使用new或malloc申请动态内存但存储空间不够。
- 数组下标越界。
- 使用野指针、迷途指针读取内存。
设备异常
- 无法打开文件,或能够打开文件但文件有损坏,从而无法读取数据。
- 正在读取磁盘文件时挪动了文件或磁盘等。
用户数据异常
- scanf输入时数据格式或类型有错误。
- 正在处理的数据库有错误。
- 程序假定的数据环境发生变化。
2 异常处理
异常处理方法
- 终止模型。在终止模型中,假设错误非常关键,以至于程序无法返回异常发生的地方继续执行。一旦异常被抛出,就表明错误无法挽回,程序不能继续执行。(实际中多用)
- 恢复模型。恢复模型是指异常处理程序的工作是修正错误, 然后重新尝试调动出问题的过程。
异常处理机制
抛出异常(throw)、检查异常(try块)、捕获异常(catch块)
- 具体地,把需要检测的程序放到try块中,把异常处理(可以是输出相关指示信息等)的程序放到catch中。如果执行一个函数时出现异常,可以不在该函数中立即处理,而是抛出异常信息,传递给它的上一级函数(调用函数),它的上一级函数捕获到这个信息后再进行处理。如果上一级函数也不处理,就逐级向上传递。如果传递到了main函数还不处理,最后将异常终止程序的执行。
- C++异常处理的机制使异常与处理可以不由同一个函数完成。这使深层次的函数专注于问题求解,不必承担处理异常的任务,减轻了深层次函数的负担,而把处理异常的任务集中到某一层级的函数中专门来解决。
3 异常处理具体实现
throw 抛出异常
throw 表达式;
- 异常发生时,抛给主调函数去处理(不会执行throw后面的额语句,将程序转移到匹配的catch,可以上一级的catch)。
- 异常以类似函数实参的方式由throw抛出,由catch捕获。
- 异常对象由throw创建,并初始化为被抛出的表达式副本,在异常处理完后撤销。
- throw后面的表达式主要关注其类型,因为C++根据类型来区分异常,对于具体的值可不必过于在意。
if(test == 0) throw test; //抛出int型异常
if(test == 1) throw 'a'; //抛出char型异常
if(test == 2) throw 333.23; //抛出double型异常
try/catch 检测捕获异常
try {
//欲检测可能发生异常的程序块
}
catch(int) { //匹配int型的异常
//对应int型的异常处理程序
}
catch(Point) { //匹配Point型的异常
//对应Point型的异常处理程序
}
catch(…) { //匹配其他类型异常,可以捕获所有异常
//对应其他类型的异常处理程序
}