C程序设计课件第5章_第1页
C程序设计课件第5章_第2页
C程序设计课件第5章_第3页
C程序设计课件第5章_第4页
C程序设计课件第5章_第5页
已阅读5页,还剩51页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2021-6-23C程序设计课件第程序设计课件第5章章1 第第5章章 异常处理异常处理 n本章学习重点掌握内容:本章学习重点掌握内容: n异常的概念、异常的产生异常的概念、异常的产生 n异常的处理机制异常的处理机制 nthrow、try和和catch的用法的用法 n捕捉所有的异常捕捉所有的异常 n异常信号的传递方式异常信号的传递方式 n标准标准C+库的异常类库的异常类 2021-6-23C程序设计课件第程序设计课件第5章章2 第第5章章 异常处理异常处理 n5.1 异常的概念异常的概念 n5.2 异常处理机制异常处理机制 n5.3 没有被捕捉的异常没有被捕捉的异常 n5.4 catch(.)使

2、用)使用 n5.5 用类的对象传递异常用类的对象传递异常 n5.6 标准标准C+库中的异常类库中的异常类 n5.7 综合应用实例综合应用实例 2021-6-23C程序设计课件第程序设计课件第5章章3 5.1 异常的概念异常的概念 5.1.1 异常的概念异常的概念 程序运行过程中,由于环境变化、用户操程序运行过程中,由于环境变化、用户操 作失误以及其它方面的原因而产生的运行时不作失误以及其它方面的原因而产生的运行时不 正常的情况,它要求程序立即进行处理,否则正常的情况,它要求程序立即进行处理,否则 将会引起程序错误甚至崩溃的现象。将会引起程序错误甚至崩溃的现象。 常见的异常有:空闲内存耗尽、请求

3、打开常见的异常有:空闲内存耗尽、请求打开 不存在的文件、被不存在的文件、被0除、打印机未打开、数组除、打印机未打开、数组 越界访问等。越界访问等。 2021-6-23C程序设计课件第程序设计课件第5章章4 5.1.2 异常的产生异常的产生 C+程序是由一些相互分离的模块组成的,程程序是由一些相互分离的模块组成的,程 序中出现错误和解决出现的错误就会分成两个部序中出现错误和解决出现的错误就会分成两个部 分分: (1)某个模块)某个模块A出现错误,但它并没有能力在出现错误,但它并没有能力在 模块模块A内解决这个错误,因此它就给出关于这个内解决这个错误,因此它就给出关于这个 错误的报告。错误的报告。

4、 (2)某个模块)某个模块B能够检测到模块能够检测到模块A发出的错误报发出的错误报 告,并处理这个错误,使出现错误造成的损失减告,并处理这个错误,使出现错误造成的损失减 到最小。到最小。 2021-6-23C程序设计课件第程序设计课件第5章章5 5.2 异常处理机制异常处理机制 5.2.1 基本概念基本概念 1抛出异常抛出异常 如果程序发生异常情况,而在当前的上下文环如果程序发生异常情况,而在当前的上下文环 境中获取不到处理这个异常的足够信息,程序境中获取不到处理这个异常的足够信息,程序 将创建一个包含出错信息的对象并将该对象抛将创建一个包含出错信息的对象并将该对象抛 出当前上下文环境,将错误

5、信息发送到更大的出当前上下文环境,将错误信息发送到更大的 上下文环境中,这个过程称为抛出(上下文环境中,这个过程称为抛出(throw) 异常。异常。 2021-6-23C程序设计课件第程序设计课件第5章章6 5.2.1 基本概念基本概念 2捕捉异常捕捉异常 对于一个抛出的异常,如果某一个模块能够对于一个抛出的异常,如果某一个模块能够 (或想要)处理这个异常,它就可以获得程序的(或想要)处理这个异常,它就可以获得程序的 控制权处理该异常,这个过程称为捕捉(控制权处理该异常,这个过程称为捕捉(catch) 异常。异常。 3处理异常处理异常 当某个当某个catch块捕捉到异常后,它就根据事先制块捕捉

6、到异常后,它就根据事先制 定的策略对异常进行处理,这就是处理异常。在定的策略对异常进行处理,这就是处理异常。在 C+中,只有中,只有catch块能够捕获异常并进行处理,块能够捕获异常并进行处理, 因此因此catch块又称为异常处理器。块又称为异常处理器。 2021-6-23C程序设计课件第程序设计课件第5章章7 5.2.1 基本概念基本概念 4C+的异常处理机制的异常处理机制 C+的异常处理机制就是将抛出异常与捕捉的异常处理机制就是将抛出异常与捕捉 异常、处理异常分离开来。抛出异常的模块并异常、处理异常分离开来。抛出异常的模块并 不负责异常的处理,它只是报告某个地方存在不负责异常的处理,它只是

7、报告某个地方存在 错误,这个报告可以帮助异常处理器解决这个错误,这个报告可以帮助异常处理器解决这个 错误。而异常处理器则根据抛出异常模块的报错误。而异常处理器则根据抛出异常模块的报 告来处理异常,如果没有模块抛出异常,就不告来处理异常,如果没有模块抛出异常,就不 会有异常的处理。会有异常的处理。 2021-6-23C程序设计课件第程序设计课件第5章章8 5.2.2 throw语句语句 抛出异常的语法格式如下:抛出异常的语法格式如下: throw 表达式表达式 这里,这里,throw后的表达式表示异常的类型,后的表达式表示异常的类型, 它可以是一个变量或一个对象。它可以是一个变量或一个对象。th

8、row语句语句 在语法上与在语法上与return语句相似。下面是两条语句相似。下面是两条 throw语句的例子。语句的例子。 throw 1; throw ( “出现异常出现异常”); 异常抛出后,程序的控制权就从异常抛出的异常抛出后,程序的控制权就从异常抛出的 地方交出,由编译器寻找匹配的异常处理器地方交出,由编译器寻找匹配的异常处理器 进行相应的处理。进行相应的处理。 2021-6-23C程序设计课件第程序设计课件第5章章9 5.2.3 try块块 try块的语法格式如下:块的语法格式如下: try 复合语句复合语句 try块必须包围能够抛出异常的语句。它提示块必须包围能够抛出异常的语句。

9、它提示 编译器到那里查找异常处理器,没有跟在编译器到那里查找异常处理器,没有跟在try 块后的块后的catch块是没有用的。块是没有用的。 try块可以包含任何块可以包含任何C+语句,甚至包含整个语句,甚至包含整个 函数。函数。 2021-6-23C程序设计课件第程序设计课件第5章章10 5.2.4 catch块块 catch块的语法格式如下。块的语法格式如下。 catch(异常类型声明异常类型声明) 异常处理语句异常处理语句 catch(异常类型声明异常类型声明) 异常处理语句异常处理语句 2021-6-23C程序设计课件第程序设计课件第5章章11 5.2.4 catch块块 ncatch

10、后括号中的异常类型声明可以是一个类后括号中的异常类型声明可以是一个类 型或一个对象声明,后边一对型或一个对象声明,后边一对“”括住的是括住的是 一组复合语句。一个一组复合语句。一个catch块相当于一个以类块相当于一个以类 型为单一参数的函数。型为单一参数的函数。 ncatch块必须直接放在块必须直接放在try块之后。块之后。catch语句语句 与与switch语句不同,它不需要在每个语句不同,它不需要在每个case语语 句后加入句后加入break用以中断后面程序的执行。用以中断后面程序的执行。 n一个一个catch 块引入一个局部域,在块引入一个局部域,在catch块内块内 声明的变量不能在

11、声明的变量不能在catch 块外引用。块外引用。 2021-6-23C程序设计课件第程序设计课件第5章章12 【例例5.2】局部域声明的变量不能被局部域外引用例题。局部域声明的变量不能被局部域外引用例题。 #include void main() try /一段可能引起异常的代码一段可能引起异常的代码 throw (出现异常!出现异常!); catch (char* message) int y = 1; cout处理了处理了char*类型的异常类型的异常endl; coutyendl; /编译错误,变量编译错误,变量y未定义未定义 2021-6-23C程序设计课件第程序设计课件第5章章13

12、5.2.5 异常处理模式异常处理模式 C+的异常处理有两种基本模式:的异常处理有两种基本模式: 1终止模式终止模式 异常抛出后,捕捉异常并退出导致异常的子程异常抛出后,捕捉异常并退出导致异常的子程 序或子系统,退出需要关闭适当的文件,析构序或子系统,退出需要关闭适当的文件,析构 适当的对象,释放适当的内存,处理需要处理适当的对象,释放适当的内存,处理需要处理 的设备等,这种方法称为终止模式。的设备等,这种方法称为终止模式。 缺省情况下,缺省情况下,C+异常处理机制采用终止方异常处理机制采用终止方 法。法。 【例例5.3】捕捉异常后直接退出的例题。捕捉异常后直接退出的例题。 2021-6-23C

13、程序设计课件第程序设计课件第5章章14 #include void func2() /一段有可能引起异常的代码一段有可能引起异常的代码 throw 1; cout其它程序语句!其它程序语句!endl; void main() try 2021-6-23C程序设计课件第程序设计课件第5章章15 func2 (); / func2 ()抛出的异常值为抛出的异常值为1 /程序抛出异常后的语句部分程序抛出异常后的语句部分 cout异常处理结束后继续执行!异常处理结束后继续执行!endl; catch (int x) /对异常的处理对异常的处理 cout处理了处理了int类型的异常类型的异常endl;

14、cout程序结束!程序结束!endl; 在采用终止模式情况下程序的运行结果为:在采用终止模式情况下程序的运行结果为: 处理了处理了int类型的异常!类型的异常! 程序结束!程序结束! 2021-6-23C程序设计课件第程序设计课件第5章章16 5.2.5 异常处理模式异常处理模式 2恢复模式恢复模式 异常抛出后,捕捉异常并试图去纠正或调异常抛出后,捕捉异常并试图去纠正或调 整引起异常的条件,然后从发生异常的地方继整引起异常的条件,然后从发生异常的地方继 续执行,这种方法称为恢复模式。续执行,这种方法称为恢复模式。 恢复模式实现起来非常困难,在实际应用恢复模式实现起来非常困难,在实际应用 中,除

15、了一些特殊的领域外,一般都不采用恢中,除了一些特殊的领域外,一般都不采用恢 复模式处理异常。复模式处理异常。 2021-6-23C程序设计课件第程序设计课件第5章章17 5.2.6 重新抛出重新抛出 n在异常处理过程中也可能存在在异常处理过程中也可能存在“单个单个catch子子 句不能完全处理这个异常句不能完全处理这个异常”的情况。那么该异的情况。那么该异 常处理器在做完局部能够做的事情后,会再一常处理器在做完局部能够做的事情后,会再一 次抛出这个异常,让函数调用链中更上级的函次抛出这个异常,让函数调用链中更上级的函 数来处理,这个过程称作重新抛出(数来处理,这个过程称作重新抛出(rethro

16、w) n重新抛出的语法形式如下:重新抛出的语法形式如下: throw; n重新抛出的还是原来捕捉到的那个异常。重新重新抛出的还是原来捕捉到的那个异常。重新 抛出只能出现在抛出只能出现在catch块中。块中。 2021-6-23C程序设计课件第程序设计课件第5章章18 【例例5.4】重新抛出捕捉的异常例题。重新抛出捕捉的异常例题。 #include void func3(int x) try / 一段有可能引起异常的代码一段有可能引起异常的代码 throw x; catch (int x) /如果异常参数如果异常参数x=0则进行处理,否则继续抛出则进行处理,否则继续抛出 if(x=0) /对异常

17、的处理对异常的处理 else cout重新抛出异常!重新抛出异常!endl; 2021-6-23C程序设计课件第程序设计课件第5章章19 throw; /重新抛出重新抛出 void main() try func3 (1); /程序其它部分程序其它部分 catch (int x) /对异常的处理对异常的处理 cout处理了处理了int类型的异常!类型的异常!endl; 2021-6-23C程序设计课件第程序设计课件第5章章20 n程序运行结果为:程序运行结果为: 重新抛出异常!重新抛出异常! 处理了处理了int类型的异常!类型的异常! n有的情况下,异常处理器在重新抛出之前会对有的情况下,异常

18、处理器在重新抛出之前会对 异常信号进行一些修改,这个修改能够影响更异常信号进行一些修改,这个修改能够影响更 高级函数调用链中的异常处理器对该异常的处高级函数调用链中的异常处理器对该异常的处 理。理。 5.2.6 重新抛出重新抛出 2021-6-23C程序设计课件第程序设计课件第5章章21 5.2.7异常规范异常规范 n异常规范规定:随着函数声明列出该函数可能抛出的异常,异常规范规定:随着函数声明列出该函数可能抛出的异常, 并保证该函数不会抛出其它类型的异常。常见附带异常说明并保证该函数不会抛出其它类型的异常。常见附带异常说明 的函数说明有以下的函数说明有以下3种情况。种情况。 (1)函数返回类

19、型)函数返回类型 函数名函数名(参数列表参数列表)throw(类型列表类型列表); (2)函数返回类型)函数返回类型 函数名函数名(参数列表参数列表) throw(); (3)函数返回类型)函数返回类型 函数名函数名(参数列表参数列表); 第一种情况,函数列出所有可能抛出的异常类型;第二种情第一种情况,函数列出所有可能抛出的异常类型;第二种情 况表示函数不会抛出任何类型的异常;第三种情况表示函数况表示函数不会抛出任何类型的异常;第三种情况表示函数 可能抛出任何类型的异常。可能抛出任何类型的异常。 n异常规范并非强制规定,因此,没有在函数说明后附带异常异常规范并非强制规定,因此,没有在函数说明后

20、附带异常 说明并非语法错误。说明并非语法错误。 2021-6-23C程序设计课件第程序设计课件第5章章22 【例例5.6】异常规范的处理例题异常规范的处理例题 void func5(int x) throw(int, char*) /x等于等于0抛出抛出int型异常,型异常,x小于小于0抛出抛出char*型异常,型异常,x大于大于0 /什么也不做什么也不做 if(x=0) throw 0; if(x0) throw error; void func6() throw() /本函数完成本函数完成10个指令周期的延时,不抛出任何异常个指令周期的延时,不抛出任何异常 int i = 0; while

21、(i10) i+; 2021-6-23C程序设计课件第程序设计课件第5章章23 5.2.7异常规范异常规范 有时,函数可能抛出没有列入异常规范的异常,有时,函数可能抛出没有列入异常规范的异常, 出现这种情况时,系统分两种情况进行处理。出现这种情况时,系统分两种情况进行处理。 (1)在函数内部(包括抛出异常的函数以及调)在函数内部(包括抛出异常的函数以及调 用该函数的函数链中的任意函数)捕捉到了这个用该函数的函数链中的任意函数)捕捉到了这个 异常,进行了处理,则程序可以继续执行。异常,进行了处理,则程序可以继续执行。 (2)异常被抛到函数外部,系统会调用)异常被抛到函数外部,系统会调用C+标标

22、准库中定义的函数准库中定义的函数unexpected(),该函数的缺,该函数的缺 省行为是调用省行为是调用terminate(),终止程序的运行。,终止程序的运行。 当然,在当然,在C+中,可以改变中,可以改变unexpected()的缺的缺 省行为。省行为。 2021-6-23C程序设计课件第程序设计课件第5章章24 5.3 没有被捕捉的异常没有被捕捉的异常 n根据异常匹配的规则,如果根据异常匹配的规则,如果try块后面的块后面的 所有的所有的catch块都没有与某一异常相匹配,块都没有与某一异常相匹配, 这时内层对异常的捕获失败,异常将进这时内层对异常的捕获失败,异常将进 入更高层的上下文

23、环境中进行匹配,这入更高层的上下文环境中进行匹配,这 个过程一直进行直到在某个层次异常处个过程一直进行直到在某个层次异常处 理器与该异常相匹配,这时才认为捕获理器与该异常相匹配,这时才认为捕获 了这个异常。了这个异常。 2021-6-23C程序设计课件第程序设计课件第5章章25 5.3 没有被捕捉的异常没有被捕捉的异常 n如果任意层的异常处理器都没有捕获到如果任意层的异常处理器都没有捕获到 这个异常,那么这个异常最终会抛给这个异常,那么这个异常最终会抛给 main()函数,如果在函数,如果在main()中还没有中还没有 找到合适的匹配,则称这个异常是找到合适的匹配,则称这个异常是“未未 捕捉的

24、捕捉的”或或“未处理的未处理的”。如果一个异。如果一个异 常未被捕捉,就会调用函数常未被捕捉,就会调用函数 terminate(),终止本程序的运行。,终止本程序的运行。 2021-6-23C程序设计课件第程序设计课件第5章章26 【例例5.7】未被捕捉的异常处理例题未被捕捉的异常处理例题 #include void func7() throw 0; void main() try func7(); catch (double d) cout进行了异常处理!进行了异常处理!endl; 2021-6-23C程序设计课件第程序设计课件第5章章27 n例子例子5.7中,中,func7()函数中抛出了

25、函数中抛出了int型的异型的异 常,最后抛给了常,最后抛给了main()函数,在函数,在main()函数函数 中也没找到合适的匹配,于是终止本程序运行,中也没找到合适的匹配,于是终止本程序运行, main()函数函数catch块后边的程序其它部分不再块后边的程序其它部分不再 执行。执行。 n如果在所有函数之外的代码出现异常,比如全如果在所有函数之外的代码出现异常,比如全 局对象的构造和析构等,如果有相应的异常处局对象的构造和析构等,如果有相应的异常处 理器捕捉到抛出的异常,则异常处理后继续理器捕捉到抛出的异常,则异常处理后继续 main()函数的执行,如果没有捕捉到抛出的函数的执行,如果没有捕

26、捉到抛出的 异常,则终止本程序运行。异常,则终止本程序运行。 5.3 没有被捕捉的异常没有被捕捉的异常 2021-6-23C程序设计课件第程序设计课件第5章章28 5.4 catch(.)使用)使用 nC+在异常处理中提供了一个能捕捉所有异常在异常处理中提供了一个能捕捉所有异常 的的catch块。块。catch块的语法格式如下:块的语法格式如下: catch() 异常处理语句异常处理语句 n其中,列表中的其中,列表中的“”表示可捕获所有的异常,表示可捕获所有的异常, 但使用省略号就不可能有参数,也不可能知道但使用省略号就不可能有参数,也不可能知道 所接受到的异常为何种类型。其它部分和普通所接受

27、到的异常为何种类型。其它部分和普通 catch块完全一样。块完全一样。 2021-6-23C程序设计课件第程序设计课件第5章章29 【例例5.9】使用使用catch(.)语句的异常处理例题语句的异常处理例题 #include void func5(int x) throw(int) /x等于等于0抛出抛出int型异常,型异常,x小于小于0抛出抛出char*型异常型异常 if(x=0) throw 0; if(x0) throw error; void main() try int x = 0; coutx; 2021-6-23C程序设计课件第程序设计课件第5章章30 func5(x); /程序

28、其它部分程序其它部分 catch(.) /对异常的处理对异常的处理 cout处理了所有类型的异常!处理了所有类型的异常!endl; cout程序结束!程序结束!endl; 程序运行结果如下:程序运行结果如下: 请输入一个请输入一个int类型数据:类型数据:0 处理了所有类型的异常!处理了所有类型的异常! 2021-6-23C程序设计课件第程序设计课件第5章章31 5.5 用类的对象传递异常用类的对象传递异常 n异常信息传递是指将异常信息传递是指将throw语句抛出的异常参数语句抛出的异常参数 传递到传递到catch块中。但在实际应用中,由于抛出块中。但在实际应用中,由于抛出 异常信息的需要,经

29、常使用类的对象传递异常。异常信息的需要,经常使用类的对象传递异常。 使用对象传递异常还有以下使用对象传递异常还有以下2个好处:个好处: (1)在)在C+中,很好地实现了中,很好地实现了RTTI(Run- Time Type Information)技术,使用对象传递)技术,使用对象传递 异常,可以很好地完成异常对象的类型匹配。异常,可以很好地完成异常对象的类型匹配。 (2)在)在C+中,很好地实现了对象的构造、销中,很好地实现了对象的构造、销 毁、转存复制等技术,可以很好的实现异常信息毁、转存复制等技术,可以很好的实现异常信息 的传递、修改和销毁等。的传递、修改和销毁等。 n同函数参数传递方式

30、一样,异常参数的传递有同函数参数传递方式一样,异常参数的传递有3 种方式:传值方式、引用方式和指针方式种方式:传值方式、引用方式和指针方式 2021-6-23C程序设计课件第程序设计课件第5章章32 5.5.1 传值方式传递异常对象传值方式传递异常对象 n按传值方式传递异常对象时,被抛出的异常都按传值方式传递异常对象时,被抛出的异常都 是局部变量,而且是临时的局部变量。也就是是局部变量,而且是临时的局部变量。也就是 说,每当在说,每当在throw语句抛出一个异常对象时,语句抛出一个异常对象时, 不管构造的对象是什么性质的变量,此时它都不管构造的对象是什么性质的变量,此时它都 会复制一份临时局部

31、变量。会复制一份临时局部变量。 【例例5.10】按传值方式传递异常对象例题。按传值方式传递异常对象例题。 #include #include using namespace std; 2021-6-23C程序设计课件第程序设计课件第5章章33 class CMyException /异常类,该类的对象作为抛出异常时传递的异常参数。异常类,该类的对象作为抛出异常时传递的异常参数。 public: CMyException (string n=none) : name(n) /根据参数根据参数n构造一个名字为构造一个名字为n的异常类对象的异常类对象 cout“构造一个构造一个CMyExceptio

32、n对象,名称对象,名称 为:为:nameendl; CMyException (const CMyException cout“拷贝一个拷贝一个CMyException对象,名称对象,名称 为:为:name endl; 2021-6-23C程序设计课件第程序设计课件第5章章34 virtual CMyException () cout “销毁一个销毁一个CMyException对象,名称对象,名称 为:为: name endl; string GetName() return name; protected: string name; /异常类对象的名字异常类对象的名字 ; void main

33、() try / 构造一个异常对象,这是个局部变量。构造一个异常对象,这是个局部变量。 CMyException obj1(obj1); 2021-6-23C程序设计课件第程序设计课件第5章章35 /下面抛出异常对象。注意:这时下面抛出异常对象。注意:这时VC编译器会复制编译器会复制 /一份新的异常对象,即调用一次一份新的异常对象,即调用一次CMyException /类的拷贝构造函数。新拷贝的对象是个临时变量。类的拷贝构造函数。新拷贝的对象是个临时变量。 throw obj1; catch(CMyException e) /当异常参数传递给当异常参数传递给e时,由于是传值方式,因时,由于是传

34、值方式,因 /此会调用一次拷贝构造函数此会调用一次拷贝构造函数 cout“捕获一个捕获一个CMyException类型异常,类型异常, 名称为:名称为:e.GetName()endl; cout程序运行结束!程序运行结束! endl; 2021-6-23C程序设计课件第程序设计课件第5章章36 5.5.1 传值方式传递异常对象传值方式传递异常对象 程序运行的结果为:程序运行的结果为: 构造一个构造一个CMyException对象,名称为:对象,名称为:obj1 拷贝一个拷贝一个CMyException对象,名称为:对象,名称为:obj1 拷贝一个拷贝一个CMyException对象,名称为:对

35、象,名称为:obj1 销毁一个销毁一个CMyException对象,名称为:对象,名称为:obj1 捕获到一个捕获到一个CMyException类型的异常,名称为:类型的异常,名称为:obj1 销毁一个销毁一个CMyException对象,名称为:对象,名称为:obj1 销毁一个销毁一个CMyException对象,名称为:对象,名称为:obj1 程序运行结束!程序运行结束! 2021-6-23C程序设计课件第程序设计课件第5章章37 5.5.1 传值方式传递异常对象传值方式传递异常对象 n例例5.10中,调用了中,调用了1次次CMyException类的构造类的构造 函数,函数,2次次CMy

36、Exception类的拷贝构造函数。类的拷贝构造函数。 n在在main() 的的try块中,定义对象块中,定义对象obj1时,调用时,调用1 次次CMyException类的构造函数。类的构造函数。 n通过通过throw语句抛出异常对象语句抛出异常对象obj1时,复制了时,复制了 一份一份obj1的临时局部变量,调用的临时局部变量,调用1次次 CMyException类的拷贝构造函数类的拷贝构造函数 n找到匹配的找到匹配的catch块后,由于是按值传递异常参块后,由于是按值传递异常参 数,又调用一次数,又调用一次CMyException类的拷贝构造函类的拷贝构造函 数。数。 2021-6-23

37、C程序设计课件第程序设计课件第5章章38 5.5.1 传值方式传递异常对象传值方式传递异常对象 n例例5.10中,调用了中,调用了3次次CMyException类的析类的析 构函数。构函数。 n在进入在进入catch块之后,进行异常处理之前,调块之后,进行异常处理之前,调 用了一次用了一次CMyException类的析构函数,这时类的析构函数,这时 析构的是析构的是try块中定义的局部变量块中定义的局部变量obj1。 n在离开在离开catch块时,又调用了两次块时,又调用了两次 CMyException类的析构函数,先析构的是进类的析构函数,先析构的是进 入入catch块是构造的异常参数块是构

38、造的异常参数obj1,然后再析,然后再析 构构throw语句创建的临时局部变量语句创建的临时局部变量obj1。 2021-6-23C程序设计课件第程序设计课件第5章章39 5.5.2 引用方式传递异常对象引用方式传递异常对象 按引用方式传递异常对象时,被抛出的异常也按引用方式传递异常对象时,被抛出的异常也 是临时局部变量。是临时局部变量。 【例例5.11】按引用方式传递异常对象的例题。按引用方式传递异常对象的例题。 #include #include using namespace std; /插入例插入例5.10中中CMyException类的定义类的定义 void main() try /

39、 构造一个异常对象,这是个局部变量。构造一个异常对象,这是个局部变量。 CMyException obj1(obj1); 2021-6-23C程序设计课件第程序设计课件第5章章40 /这里抛出异常对象。注意:这时这里抛出异常对象。注意:这时VC编译器会复制编译器会复制 /一份新的异常对象,即调用一次一份新的异常对象,即调用一次CMyException / 类的拷贝构造函数。新拷贝的对象是个临时变量。类的拷贝构造函数。新拷贝的对象是个临时变量。 throw obj1; catch(CMyException cout程序运行结束!程序运行结束! endl; 2021-6-23C程序设计课件第程序设

40、计课件第5章章41 5.5.2 引用方式传递异常对象引用方式传递异常对象 程序运行的结果为:程序运行的结果为: 构造一个构造一个CMyException异常对象,名称为:异常对象,名称为:obj1 拷贝一个拷贝一个CMyException异常对象,名称为:异常对象,名称为:obj1 销毁一个销毁一个CMyException异常对象,名称为:异常对象,名称为:obj1 捕获到一个捕获到一个CMyException类型的异常,名称为:类型的异常,名称为:obj1 销毁一个销毁一个CMyException异常对象,名称为:异常对象,名称为:obj1 2021-6-23C程序设计课件第程序设计课件第5

41、章章42 5.5.2 引用方式传递异常对象引用方式传递异常对象 n例例5.11中,调用了中,调用了2次次CMyException类的构类的构 造函数。造函数。 n在在main() 的的try块中,定义对象块中,定义对象obj1时,调用时,调用 1次次 CMyException类的构造函数。类的构造函数。 n通过通过throw语句抛出异常对象语句抛出异常对象obj1时,复制了时,复制了 一份一份obj1的临时局部变量,调用的临时局部变量,调用1次次 CMyException类的拷贝构造函数类的拷贝构造函数 n由于由于catch块是按引用方式传递异常对象,传递块是按引用方式传递异常对象,传递 给给

42、catch块的是临时异常对象的引用,因而不需块的是临时异常对象的引用,因而不需 要调用异常类的构造函数。要调用异常类的构造函数。 2021-6-23C程序设计课件第程序设计课件第5章章43 5.5.2 引用方式传递异常对象引用方式传递异常对象 n在例在例5.11中,调用了中,调用了2次次CMyException类的类的 析构函数。析构函数。 n在进入在进入catch块之后,进行异常处理之前,调块之后,进行异常处理之前,调 用了一次用了一次CMyException类的析构函数,这时类的析构函数,这时 析构的是析构的是try块中定义的局部变量块中定义的局部变量obj1。 n在退出在退出catch块

43、时,又调用了一次块时,又调用了一次 CMyException类的析构函数,这时析构的是类的析构函数,这时析构的是 调用调用throw语句时构建的临时异常对象。语句时构建的临时异常对象。 2021-6-23C程序设计课件第程序设计课件第5章章44 5.5.3 指针方式传递异常对象指针方式传递异常对象 与传值方式和引用方式传递异常对象相比,在与传值方式和引用方式传递异常对象相比,在 按指针方式传递异常时,异常对象的构造方式按指针方式传递异常时,异常对象的构造方式 有很大的不同。它要么是在堆中动态构造的异有很大的不同。它要么是在堆中动态构造的异 常对象,要么是静态全局对象,而不能是局部常对象,要么是

44、静态全局对象,而不能是局部 变量。变量。 【例例5.12】按引用方式传递异常的例题。按引用方式传递异常的例题。 #include #include using namespace std; /插入例插入例5.10中中CMyException类的定义类的定义 void main() 2021-6-23C程序设计课件第程序设计课件第5章章45 try/ 动态在堆中构造的异常对象,调用一次构造函数。动态在堆中构造的异常对象,调用一次构造函数。 throw new CMyException (obj1); / 注意:这里是定义了按指针方式传递异常对象注意:这里是定义了按指针方式传递异常对象 catch

45、(CMyException* e) / 此处传递给此处传递给e的实际是上面动态对象的地址,的实际是上面动态对象的地址, /因此不调用任何构造函数。因此不调用任何构造函数。 cout“捕获到一个捕获到一个CMyException*类型的异类型的异 常,名称为:常,名称为:GetName()endl; delete e; /动态创建的对象需要销毁动态创建的对象需要销毁 程序运行的结果为:程序运行的结果为: 构造一个构造一个CMyException异常对象,名称为:异常对象,名称为:obj1 捕获到一个捕获到一个CMyException*类型的异常,名称为:类型的异常,名称为:obj1 销毁一个销毁一个CMyException异常对象,名称为:异常对象,名称为:obj1 2021-6-23C程序设计课件第程序设计课件第5章章46 5.5.3 指针方式传递异常对象指针方式传递异常对象 n例例5.12中,只在异常抛出时调用了一次中,只在异常抛出时调用了一次 CMyException类的构造函数。类的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论