第1章 C++程序设计基础 网络游戏开发-C++程序设计
第10章 异常处理 异常处理的概念 异常处理的机制 多层级间的异常处理 异常处理的堆栈操作 异常处理的机制和实现 多层级间的异常处理 了解异常处理的机制 掌握异常处理的方法 掌握多层级间的异常处理方法 了解异常处理中的堆栈操作
第10章 异常处理 10.1异常处理在C++中的实现 10.1.1 异常处理的概念和使用条件 程序运行中的某些错误(或意外情况)不可避免但可以预料。 例如,做除法或模运算时使用的除数为0。 if(y==0){ cout<<"Error occuring -- Divided by 0!";exit(1);}
第10章 异常处理 10.1异常处理在C++中的实现 10.1.1 异常处理的概念和使用条件 异常处理的特点: 1)当引发异常时,要提供有意义的文本; 2)只在必要时才会引发异常; 3)当函数的参数不符合条件时,不引发异常; 4)不能为正常的错误或可预期的错误产生异常
第10章 异常处理 10.1异常处理在C++中的实现 10.1.2 异常处理的实现 C++中提供的对异常进行处理的机制,那就是在程序中使用try、catch和throw。 通过throw抛掷异常后, 系统将跳转到与所抛掷的实参(表达式)类型完全匹配的catch块,执行完catch块后将不再返回,继而转到catch块序列的最后一个catch 块的下一语句处去执行。
第10章 异常处理 10.1异常处理在C++中的实现 10.1.2 异常处理的实现 try块 通过try可构成try块,用于标记运行时可能出现异常的程序代码。 异常来源: try 块中直接抛掷的异常 通过所调用的“下层”函数而间接抛掷的各种异常 注意:抛掷异常是通过throw 语句来完成的。 try { "受监控“ 的语句序列(通常包含抛掷异常的throw 语句) }
第10章 异常处理 10.1异常处理在C++中的实现 10.1.2 异常处理的实现 catch块 通过catch可构成catch块,它紧跟在try块的后面 用于监视并捕获运行时可能出现的某一种类(类型)的异常, 对此种异常进行具体的处理(处理程序代码包含在catch块之中)。 catch (欲捕获的异常类型及形参名字) { 对该类型异常的具体处理语句序列 }
第9章 模板与STL 10.1异常处理在C++中的实现 10.1.2 异常处理的实现 catch块 可以只给出异常类型,这适合于异常处理中不使用形参的情况 允许捕获任何类型的异常,在catch 块首括号用省略号代替参数(即“...”) 以省略号为参数的catch 块应该在其他catch块之后,否则,其后的所有catch 块都将起不到任何作用。
第10章 异常处理 10.1异常处理在C++中的实现 10.1.2 异常处理的实现 throw 表达式 表达式:一个变量或对象、一个常量或字符串等 系统将根据表达式的值类型来与各catch块首括号中形参的异常类型进行“对比”, 若“匹配”成功(要求类型完全一致,系统并不自动进行类型转换),则跳转到那一catch块去执行,即进行相应的异常处理; 若所有匹配都不成功,则将自动去执行一个隐含的系统函数“abort()”来终止整个程序的运行。
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.1 多级多层处理的机制 1)允许抛掷异常的语句处于被调用函数中,而catch语句位于主调函数中。 unsigned short numMul(unsigned short sNum1, unsigned short sNum2) { int nExc = 0; unsigned short sProduct = sNum1 * sNum2; // 当结果超出数据表达范围时就抛出异常 if ( sProduct < sNum1 || sProduct < sNum2) { throw nExc; } else { return sProduct; }
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.1 多级多层处理的机制 int _tmain(int argc, _TCHAR* argv[]) { unsigned short s1 = 50000, s2 = 40000; unsigned short sProduct; try { sProduct = numMul(s1, s2); printf("乘积=%d\n", sProduct); } catch (int nExc) { printf("错误代码为:%d\n", nExc); } return 0;
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.1 多级多层处理的机制 2)允许在同一程序中使用多个try块,而且这些try块可以处于不同的位置并具有不同的层次级别。
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.2 多级多层处理的综合实例 #include <iostream> using namespace std; class myExcepCla { //自定义的myExcepCla 类(类型) char message[100]; public: myExcepCla(char* msg) { //构造函数,实参带来私有字符串数据message strcpy(message, msg); } char* GetErrMsg() { //成员函数,获取私有数据message 字符串 return message; }; void InData(); //函数原型
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.2 多级多层处理的综合实例 void main() { try InData(); //调用自定义函数InData,其中可能抛掷异常 cout<<"End try block!"<<endl; } catch (char * str) //捕获“char *”类型的异常并进行处理 cout<<"main-catch::"<<str<<endl; catch (myExcepCla ob) //捕获“myExcepCla”类型的异常并进行处理 cout<<"main-catch::"<<ob.GetErrMsg()<<endl;
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.2 多级多层处理的综合实例 catch ( ... ) { //捕获“其他”任何异常并进行处理 cout<<"main-catch::"<<"Caught unknown exception!"<<endl; } cout<<"End main function!"<<endl; //本层次的某个异常处理结束后, //均转到此处执行该语句 void f(int val) //自定义函数f,负责判断val 是否为11 或22, if(val==11) //输入值为11,抛掷一个int 型异常 throw val; if(val==22) //输入值为22,抛掷一个double 型异常 throw 123.86;
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.2 多级多层处理的综合实例 void InData() { int val; cout<<"Input a INTEGER(from -50 -- 50, excpt 0 、11、22):"; cin>>val; if (val==0) //若输入值等于0,抛掷“char*”类异常,在main 中被捕获处理。 throw "Exception : value equal 0!"; try { //处于InData 中的try 程序块,它为“受监控”的另一个程序块 if (val<-50) myExcepCla exc("Exception : value less than -50!"); throw exc; //该异常将被main 中try 后的“catch (myExcepCla ob)” } if (val>50) throw "Exception : value greater than 50!"; //在本try 后的catch 块序列中被捕获处理 else f(val); //被调函数f 中可能抛掷异常 cout<<"OK! value="<<val<<endl; //不发生异常时,屏幕显示出输入值val
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.2 多级多层处理的综合实例 catch (int i) { cout<<"InData-catch::"<<"Caught INT exception! i="<<i<<endl; } catch (char * str) //捕获“char *”类型的异常并进行处理 cout<<"InData-catch::"<<str<<endl;
第10章 异常处理 10.2多级多层捕获与处理机制 10.2.2 多级多层处理的综合实例 注意: 异常被某一个层次的catch块所捕获,程序执行完catch块代码后, 将从其所在的块序列之后的下一语句处继续执行。
第10章 异常处理 10.3 异常处理中的堆栈展开 堆栈展开的原因: 执行完catch块后将不再返回到throw语句之后,继而转到catch块序列的最后一个catch块的“下一语句”处去执行。 throw的“跳转”实际上相当于跳出了所在作用域,所以系统将自动检查在那些作用域中已经构造但尚未析构的处于堆栈中的局部对象(与变量),并自动进行相应的退栈与析构处理。
检查try块的已构造但尚未析构的堆栈中的局部对象 第10章 异常处理 10.3 异常处理中的堆栈展开 堆栈展开的过程 抛掷异常 找到catch块 对 “形参”进行“初始化” 检查try块的已构造但尚未析构的堆栈中的局部对象 局部对象退栈与析构 执行catch块代码
第10章 异常处理 10.3 异常处理中的堆栈展开 异常的适用范围 在C++程序设计中有一些和异常处理的用法相关的设计事项 因为抛出异常不像正常函数调用那样快, 所以异常处理应该用在独立开发的不同程序部分之间用于不正常情况的通信
第10章 异常处理 小结 本章主要讲解异常处理的基础知识 异常处理的概念 异常处理的机制 多层级间的异常处理 异常处理的堆栈操作
第10章 异常处理 自测题 1.当程序中产生异常时,程序一定会被强制结束。( ) 2.异常只在try块中产生,在非try块中不会产生。( ) 1.当程序中产生异常时,程序一定会被强制结束。( ) 2.异常只在try块中产生,在非try块中不会产生。( ) 3.在catch 块首括号中仅写上3 个点符号(即“...”)时此块不处理任何异常。( ) 4.若try块后找不到相应的catch块来处理异常,则程序将忽略这个异常继续运行。( ) 5.在同一程序中,try块的数量一定和catch块的数量一样多。( )
第10章 异常处理 自测题 1.当程序中产生异常时,程序一定会被强制结束。( X ) 2.异常只在try块中产生,在非try块中不会产生。( X ) 3.在catch 块首括号中仅写上3 个点符号(即“...”)时此块不处理任何异常。( X ) 4.若try块后找不到相应的catch块来处理异常,则程序将忽略这个异常继续运行。( X ) 5.在同一程序中,try块的数量一定和catch块的数量一样多。( X )
第10章 异常处理 课后作业 【作业1】输入一组数,实现一个累加和函数,当累加和超过数据的表示范围时,产生异常。