第15章 C++异常处理
C++程序设计
15.6.2 异常的典型使用
1. 2. 3. 4. 5. 6. 7. 8. 9. 随时使用异常规格说明 起始于标准异常 套装用户自己的异常 使用异常层次 多重继承 引用”而非“ 用“引用”而非“值”去捕获 在构造函数中抛出异常 不要在析构函数中导致异常 避免无保护的指针
C++程序设计
异常处理的执行过程如下: (1)控制通过正常的顺序执行到达try语句,然后 执行try块内的保护段。 (2)如果在保护段执行期间没有引起异常,那么 跟在try块后的catch子句就不执行,程序从异常被抛掷 的try块后跟随的最后一个catch子句后面的语句继续执 行下去。 (3)如果在保护段执行期间或在保护段调用的任 何函数中有异常被抛掷,则从通过throw运算数创建的 对象中创建一个异常对象。编译器从能够处理抛掷类 型的异常的更高执行上下文中寻找一个catch子句(或 一个能处理任何类型异常的catch处理程序)。catch处 理程序按其在try块后出现的顺序被检查。如果没有找 到合适的处理程序,则继续检查下一个动态封闭的try 块。此处理继续下去直到最外层的封闭try块被检查完。
C++程序设计
在一般情况下,被调用函数直接检测到异常条件 的存在并使用throw引发一个异常(注意,C++语言的 异常是由程序员控制引发的,而不是由计算机硬件或 程序运行环境控制的);在上层调用函数中使用try检 测函数调用是否引发异常,检测到的各种异常由catch 捕获并作相应处理。
15.3.1 异常处理的语法
C++程序设计
(4)如果匹配的处理器未找到,则运行函数 terminate将被自动调用,而函数terminate的默认功能是 调用abort终止程序。 (5)如果找到了一个匹配的catch处理程序,且它 通过值进行捕获,则其形参通过拷贝异常对象进行初 始化。如果它通过引用进行捕获,则参量初始化为指 向异常对象。在形参被初始化之后,开始“循环展开 栈”的过程,这包括对那些在与catch处理器相对应的 try块开始和异常丢弃地点之间创建的(但尚未析构的) 所有自动对象的析构。析构以与构造相反的顺序进行。 然后执行catch处理程序,接下来程序跳转到跟随在最 后处理程序之后的语句。 注意:catch处理程序的出现顺序很重要,因为在 一个try块中,异常处理程序是按照它出现的顺序被检 查的。
C++程序设计
15.5 多路捕获
很多程序可能有若干不同种类的运行错误,它们 可以使用异常处理机制,每种错误可与一个类,一种 数据类型或一个值相关。这样,在程序中就会出现多 路捕获。 例15-5
C++程序设计
15.6 含有异常的程序设计
15.6.1 何时避免异常
异常并不能处理所发生的所有问题。实际上若对 异常过分的考虑,将会遇到许多麻烦。下面的段落指 出异常不能被保证的情况。 1. 异步事件 2. 普通错误情况 3. 流控制 4. 不强迫使用异常 5. 新异常,老代码 新异常,
C++程序设计
为处理可预料的错误,常用的典型方法是让被调 用函数返回某一个特别的值(或将某个按引用调用传 递的参数设置为一个特别的值),而外层的调用程序 则检查这个错误标志,从而确定是否产生了某一类型 的错误。另一种典型方法是当错误发生时跳出当前的 函数体,控制转向某个专门的错误处理程序,从而中 断正常的控制流。这两种方法都是权宜之计,不能形 成强有力的结构化异常处理模式。 异常处理机制是用于管理程序运行期间错误的一 种结构化方法。所谓结构化是指程序的控制不会由于 产生异常而随意跳转。异常处理机制将程序中的正常 处理代码与异常处理代码显式区别开来,提高了程序 的可读性。
C++程序设计
15.1 异常处理概述
程序可能按编程者的意愿终止,也可能因为程序 中发生了错误而终止。例如,程序执行时遇到除数为0 或下标越界,这时将产生系统中断,从而导致正在执 行的程序提前终止。 程序的错误有两种,一种是编译错误,即语法错 误。如果使用了错误的语法、函数、结构和类,程序 就无法被生成运行代码。另一种是在运行时发生的错 误,它分为不可预料的逻辑错误和可以预料的运行异 常。
在C++程序中,任何需要检测异常的语句(包括函 数调用)都必须在try语句块中执行,异常必须由紧跟 着try语句后面的catch语句来捕获并处理。因而,try与 catch总是结合使用。throw、try和catch语句的一般语法 如下:
C++程序设计
throw <表达式>; try { //try语句块 } catch(类型1 参数1) { //针对类型1的异常处理 } catch (类型2 参数2) { //针对类型2的异常处理 } … catch (类型n 参数n) { //针对类型n的异常处理 }
C++程序设计
15.2 异常处理的基本思想
对于中小型程序,一旦发生异常,一般是将程序 立即中断执行,从而无条件释放系统所有资源。而对 于比较大的程序来说,如果出现异常,应该允许恢复 和继续执行。恢复的过程就是把产生异常所造成的恶 劣影响去掉,中间一般要涉及一系列的函数调用链的 退栈,对象的析构,资源的释放等。继续运行就是异 常处理之后,在紧接着异常处理的代码区域中继续运 行。
C++程序设计
15.3 C++异常处理的实现
C++语言异常处理机制的基本思想是将异常的检测 与处理分离。当在一个函数体中检测到异常条件存在, 但无法确定相应的处理方法时,将引发一个异常,并 由函数的直接或间接调用检测并处理这个异常。这一 基本思想用3个保留字实现:throw、try和catch。其作 用是: (1)try:标识程序中异常语句块的开始。 (2)throw:用来创建用户自定义类型的异常错 误。 (3)catch:标识异常错误处理模块的开始。
C++程序设计
15.3.2 异常处理的规则
(1)try分程序必须出现在前,catch紧跟出现在后。 catch之后的圆括号中必须含有数据类型,捕获是利用 数据类型匹配实现的。 (2)如果程序内有多个异常错误处理模块,则当 异常错误发生时,系统自动查找与该异常错误类型相 匹配的catch模块.查找次序为catch出现的次序。 (3)如果异常错误类型为C++的类,并且该类有 其基类,则应该将派生类的错误处理程序放在前面, 基类的错误处理程序放在后面。 (4)如果一个异常错误发生后,系统找不到一个 与该错误类型相匹配的异常错误处理模块,则调用预 定义的运行时刻终止函数,默认情况下是abort。
C++程序设计
第15章 异常处理
15.1 15.2 15.3 15.4 15.5 15.6 异常处理概述 异常处理的基本思想 C++异常处理的实现 标准C++库中的异常类 多路捕获 含有异常的程序设计
C++程序设计
在编写程序时,应该考虑确定程序可能出 现的错误,然后加入处理错误的代码。也就是 说,在环境条件出现异常情况下,不会轻易出 现死机和灾难性的后果,而应;+提供了异常处理机 制,它使得程序出现错误时,力争做到允许用 户排除环境错误,继续运行程序。
C++程序设计
15.4 标准C++库中的异常类
标准C++库中包含9个异常类,它们可以分为运行 时异常和逻辑异常: length_error //运行时长度异常 domain_error //运行时域异常 out_of_range_error //运行时越界异常 invalid_argument //运行时参数异常 range_error //逻辑异常,范围异常 overflow_error //逻辑异常,溢出(上)异常 overflow_error //逻辑异常,溢出(下)异常 标准C++库中的这些异常类并没有全部被显式使 用,因为C++标准库中很少发生异常,但是这些标准 C++库中的异常类可以为编程人员,特别式自己类库 的开发者提供一些经验。