《嵌入式Linux下C+程序设计--09异常处理.ppt》由会员分享,可在线阅读,更多相关《嵌入式Linux下C+程序设计--09异常处理.ppt(16页珍藏版)》请在人人文库网上搜索。
1、嵌入式Linux下QT程序设计,主讲:成宝宗,主要内容:,异常处理机制 异常实现 异常执行过程 异常接口声明 异常处理中的构造与析构,异常处理的实现机制,抛掷异常的程序段 . throw 表达式; .,捕获并处理异常的程序段 try 复合语句 catch(异常类型声明) 复合语句 catch(异常类型声明) 复合语句 ,示例:,#include using namespace std; int fun(int x, int y)/抛出异常 if (y = 0)throw y; return x/y; int main(int argc, char *argv) try/捕获异常 cout fu。
2、n(34,5)endl; cout fun(4,0)endl; catch(int)/处理int异常 cout y = 0endl; catch(.)/处理所有异常 cout catch(.)endl; ,异常处理的实现,异常处理的语法 1throw语法 throw; 当某段程序发现了自己不能处理的异常,就可以使用throw语句将这个异常抛掷给调用者。throw语句的使用与return语句相似,如果程序中有多处要抛掷异常,应该用不同的表达式类型来互相区别,表达式的值不能用来区别不同的异常。,2try块语法 try 复合语句 try语句后的复合语句是代码的保护段。如果预料某段程序代码(或对某个函。
3、数的调用)有可能发生异常,就将它放在try语句之后。如果这段代码(或被调函数)运行时真的遇到异常情况,其中的throw表达式就会抛掷这个异常。,异常处理的实现,3catch语法 catch(异常类型1参数1) /针对异常类型1的处理语句 catch(异常类型2参数2) /针对异常类型2的处理语句 . catch(异常类型n参数n) /针对异常类型n的处理语句 catch语句后的复合语句是异常处理程序,捕获由throw表达式抛掷的异常。异常类型声明部分指明语句所处理的异常类型,它与函数的形参相类似,可以是某个类型的值,也可以是引用。这里的类型可以是任何有效的数据类型,包括C+的类。当异常被抛掷以。
4、后,catch语句便依次被检查。,异常处理的实现,异常处理的执行过程如下: 控制通过正常的顺序执行到达try语句,然后执行try块内的保护段。 如果在保护段执行期间没有引起异常,那么跟在try块后的catch语句就不执行,程序从异常被抛掷的try块后跟随的最后一个catch语句后面的语句继续执行下去。,异常处理的执行过程,如果在保护段执行期间或在保护段调用的任何函数中(直接或间接的调用)有异常被抛掷,则从通过throw创建的对象中创建一个异常对象(这隐含指可能包含一个拷贝构造函数)。 这一点上,编译器能够处理抛掷类型的异常,在更高执行上下文中寻找一个catch语句(或一个能处理任何类型异常的c。
5、atch处理程序)。catch处理程序按其在try块后出现的顺序被检查。如果没有找到合适的处理程序,则继续检查下一个动态封闭的try块。此处理继续下去,直到最外层的封闭try块被检查完。,异常处理的执行过程,如果匹配的处理器未找到,则terminate()将被自动调用,而函数terminate()的默认功能是调用abort终止程序。 如果找到了一个匹配的catch处理程序,且它通过值进行捕获,则其形参通过拷贝异常对象进行初始化。如果它通过引用进行捕获,则参量被初始化为指向异常对象,在形参被初始化之后,“循环展开栈”的过程开始。这包括对那些在与catch处理器相对应的try块开始和异常丢弃地点之。
6、间创建的(但尚未析构的)所有自动对象的析构。,异常处理的执行过程,为了加强程序的可读性,使用户能够方便地知道所使用的函数会抛掷哪些异常,可以在函数的声明中列出这个函数可能抛掷的所有异常类型。例如: voidfun()throw(A,B,C,D) 这表明函数throw()能够且只能够抛掷类型A、B、C、D的异常。 如果在函数的声明中没有包括异常接口声明,则此函数可以抛掷任何类型的异常。 例如: void fun(); 一个不抛掷任何类型异常的函数可以进行如下形式的声明: void fun() throw();,异常接口声明,异常处理中的构造与析构,C+异常处理的真正能力不仅在于它能够处理各种不同。
7、类型的异常,还在于它具有在异常抛掷前为构造的所有局部对象自动调用析构函数的能力。 在程序中,找到一个匹配的catch异常处理后,如果catch语句的异常类型声明是一个值参数,则其初始化方式是复制被抛掷的异常对象;如果catch语句的异常类型声明是一个引用,则其初始化方式是使该引用指向异常对象。 当catch语句的异常类型声明参数被初始化后,栈的展开过程便开始了。这包括从对应的try块开始到异常被抛掷处之间对构造(且尚未析构)的所有自动对象进行析构。析构的顺序与构造的顺序相反。然后程序从最后一个catch处理之后开始恢复执行。,#include using namespace std; void。
8、 MyFunc( void ); class Expt public: Expt(); Expt(); const char *ShowReason() const return Expt类异常。; ; class Demo public: Demo(); Demo(); ; Demo:Demo() cout构造 Demo.endl; Demo:Demo() cout析构 Demo.endl; void MyFunc() Demo D; cout在MyFunc()中抛掷Expt类异常。endl; throw Expt(); ,int main() cout在main函数中。endl; try 。
9、cout在try块中,调用MyFunc()。 endl; MyFunc(); catch( Expt E ) cout在catch异常处理程序中。endl; cout捕获到Expt类型异常:; coutE.ShowReason()endl; catch( char *str ) cout捕获到其他的异常:strendl; cout回到main函数。从这里恢复执行。 endl; return 0; ,在catch异常处理程序中 捕获到Expt类型异常:Expt类异常 回到main()函数,从这里恢复执行 注意,本例中,在两个catch处理器中都说明了异常参量(catch语句的参量): catch。
10、(ExptE) /. catch(char*str) /.,其实,也可以不说明这些参量(E和str)。在很多情况下,只要通知处理程序有某个特定类型的异常已经产生就足够了。但是在需要访问异常对象时就要说明参量,否则,将无法访问catch处理程序语句中的那个对象。例如: catch(Expt) /在这里不能访问Expt异常对象 用一个不带操作数的throw表达式可以将当前正被处理的异常再次抛掷。,这样一个表达式只能出现在一个catch处理程序中或catch处理程序内部调用的函数中。再次抛掷的异常对象是源异常对象(不是拷贝)。例如: try throwCSomeOtherException(); catch(.)/处理所有异常 /对异常作出响应(也许仅仅是部分的) /. throw;/将异常传给某个其它处理器。