第15章 异常处理
第15章
15.1 15.2 15.3 15.4 15.5 15.6
异常处理
异常处理概述 异常处理的基本思想 C++异常处理的实现 标准C++库中的异常类 多路捕获 含有异常的程序设计
2008年3月6日星期四1时2分44秒 Author:Joly,Xiang.
在编写程序时,应该考虑确定程序可能出现 的错误,然后加入处理错误的代码。也就是说, 在环境条件出现异常情况下,不会轻易出现死机 和灾难性的后果,而应有正确合理的表现。这就 是异常处理。C++提供了异常处理机制,它使得 程序出现错误时,力争做到允许用户排除环境错 误,继续运行程序。
throw <表达式>; try { //try语句块 } catch(类型1 参数1) { //针对类型1的异常处理 } catch (类型2 参数2) { //针对类型2的异常处理 } … catch (类型n 参数n) { //针对类型n的异常处理 }
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
2008年3月6日 Author:Joly,Xiang.
(4)如果匹配的处理器未找到,则运行函数 terminate将被自动调用,而函数terminate的默认功能是 调用abort终止程序。 (5)如果找到了一个匹配的catch处理程序,且它 通过值进行捕获,则其形参通过拷贝异常对象进行初 始化。如果它通过引用进行捕获,则参量初始化为指 向异常对象。在形参被初始化之后,开始“循环展开 栈”的过程,这包括对那些在与catch处理器相对应的 try块开始和异常丢弃地点之间创建的(但尚未析构的) 所有自动对象的析构。析构以与构造相反的顺序进行。 然后执行catch处理程序,接下来程序跳转到跟随在最 后处理程序之后的语句。 注意:catch处理程序的出现顺序很重要,因为在 一个try块中,异常处理程序是按照它出现的顺序被检 查的。
很多程序可能有若干不同种类的运行错误,它们可 以使用异常处理机制,每种错误可与一个类,一种数据 类型或一个值相关。这样,在程序中就会出现多路捕获。 例15-5
//代码区1 try{ //代码区2 String s("abcdefghijklmnop", g(s); }
多路捕捉举例(例15-5)
catch(String::Range r)
{
throw Range(k);
} private: char* p; int len; static int max; }; int String::max = 20; String::String(char* str, int si){ if(si<0 || max<si) } <<r.index <<endl;
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
2008年3月6日 Author:Joly,Xiang.
在一般情况下,被调用函数直接检测到异 常条件的存在并使用throw引发一个异常(注意, C++语言的异常是由程序员控制引发的,而不 是由计算机硬件或程序运行环境控制的);在 上层调用函数中使用try检测函数调用是否引发 异常,检测到的各种异常由catch捕获并作相应 处理。
2008年3月6日 Author:Joly,Xiang.
异常处理的执行过程如下:
(1)控制通过正常的顺序执行到达try语句,然后 执行try块内的保护段。 (2)如果在保护段执行期间没有引起异常,那么 跟在try块后的catch子句就不执行,程序从异常被抛掷 的try块后跟随的最后一个catch子句后面的语句继续执 行下去。 (3)如果在保护段执行期间或在保护段调用的任 何函数中象。编译器从能够处理抛掷类 型的异常的更高执行上下文中寻找一个catch子句(或 一个能处理任何类型异常的catch处理程序)。catch处 理程序按其在try块后出现的顺序被检查。如果没有找 到合适的处理程序,则继续检查下一个动态封闭的try 块。此处理继续下去直到最外层的封闭try块被检查完。
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
2008年3月6日 Author:Joly,Xiang.
15.3 C++异常处理的实现
C++语言异常处理机制的基本思想是将异常 的检测与处理分离。当在一个函数体中检测到异 常条件存在,但无法确定相应的处理方法时,将 引发一个异常,并由函数的直接或间接调用检测 并处理这个异常。这一基本思想用3个保留字实 现:throw、try和catch。其作用是: (1)try:标识程序中异常语句侦测块的开 始。 (2)throw:用来创建用户自定义类型的异 常错误。 (3)catch:标识异常错误处理模块的开始。
©2007 iSoftStone Holdings Ltd. All Rights Reserved. 2008年3月6日 Author:Joly,Xiang.
15.3.2 异常处理的规则
(1)try分程序必须出现在前,catch紧跟出现在后。 catch之后的圆括号中必须含有数据类型,捕获是利用数 据类型匹配实现的。 (2)如果程序内有多个异常错误处理模块,则当异 常错误发生时,系统自动查找与该异常错误类型相匹配 的catch模块.查找次序为catch出现的次序。 (3)如果异常错误类型为C++的类,并且该类有其 基类,则应该将派生类的错误处理程序放在前面,基类 的错误处理程序放在后面。 (4)如果一个异常错误发生后,系统找不到一个与 该错误类型相匹配的异常错误处理模块,则调用预定义 的运行时刻终止函数,默认情况下是abort。
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
2008年3月6日 Author:Joly,Xiang.
15.1 异常处理概述
程序可能按编程者的意愿终止,也可能因为 程序中发生了错误而终止。例如,程序执行时遇 到除数为0或下标越界,这时将产生系统中断, 从而导致正在执行的程序提前终止。 程序的错误有两种,一种是编译错误,即语 法错误。如果使用了错误的语法、函数、结构和 类,程序就无法被生成运行代码。另一种是在运 行时发生的错误,它分为不可预料的逻辑错误和 可以预料的运行异常。
cerr <<"->out of range: "
//代码区3
catch(String::Size)
{ cerr <<"size illegal!\n"; } cout <<"The program will be continued here.\n\n"; //代码区4 } void main() { //代码区5 f(); cout <<"These code is not effected by probably exception in f().\n"; } 运行结果为: abcdefghij The program will be continued here These code is not effected by probably exception in f().
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
2008年3月6日 Author:Joly,Xiang.
15.2 异常处理的基本思想
对于中小型程序,一旦发生异常,一般 是将程序立即中断执行,从而无条件释放 系统所有资源。而对于比较大的程序来说, 如果出现异常,应该允许恢复和继续执行。 恢复的过程就是把产生异常所造成的恶劣 影响去掉,中间一般要涉及一系列的函数 调用链的退栈,对象的析构,资源的释放 等。继续运行就是异常处理之后,在紧接 着异常处理的代码区域中继续运行。
15.3.1 异常处理的语法
在C++程序中,任何需要检测异常的语句 (包括函数调用)都必须在try语句块中执行, 异常必须由紧跟着try语句后面的catch语句来捕 获并处理。因而,try与catch总是结合使用。 throw、try和catch语句的一般语法如下:
©2007 iSoftStone Holdings Ltd. All Rights Reserved. 2008年3月6日 Author:Joly,Xiang.
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
2008年3月6日 Author:Joly,Xiang.
15.4 标准C++库中的异常类
标准C++库中包含9个异常类,它们可以分为运行 时异常和逻辑异常: length_error //运行时长度异常 domain_error //运行时域异常 out_of_range_error //运行时越界异常 invalid_argument //运行时参数异常 range_error //逻辑异常,范围异常 overflow_error //逻辑异常,溢出(上)异常 overflow_error //逻辑异常,溢出(下)异常 标准C++库中的这些异常类并没有全部被显式使 用,因为C++标准库中很少发生异常,但是这些标准 C++库中的异常类可以为编程人员,特别式自己类库 的开发者提供一些经验。
©2007 iSoftStone Holdings Ltd. All Rights Reserved.
2008年3月6日 Author:Joly,Xiang.