您的位置:首页 > 其它

<try 块 和 异常处理>

2016-06-10 15:39 183 查看
异常是操作系统的机制,起始工作都交由给各语言的编译器进行处理。异常其实就是操作系统提供给我们应用程序一个改过自新的机会,当应用程序在正常运行的过程中出现了一些以外的错误,或者不应该发生的事情,这种事件的发生就是异常!

这样程序中就应该包含异常检测代码(用以检查出现的异常),以及处理异常的异常处理程序(handler)。

|

|——>> 正常运行中

|

|——>> 出现异常

|

|——>> 异常检测代码检测到异常

|

|

|——>> 检测到异常后(检查异常的代码:EXCUTION_EXCEPTION_SEARCH EXECUTION_EXCEPTION_HANDLER),查找对应的异常处理程序

|

|

|——>> 如果正在被调试,系统将会向调试器发送 EXCEPTION_DEBUG_EVENT 消息,并且挂起程序。

|

|——>> 未被调试,就会查找程序的异常处理程序(单个异常处理程序状况下)

|——>> 若是第一个异常处理程序不能处理,则根据异常处理程序链查找能够处理异常的处理程序。

|

|||——>>须知:线程的偏移0x0h处就是TIB的偏移0x00h处即为_EXCEPTION_REGISTRATION_RECORD结构变量Exceptionlist,包含了当前异常处理程序地址和上一个异常处理程序地址。

|||——>>须知:然后系统会向发生异常的线程压入 EXCEPTIONPOINTER 结构,包含两个成员:1.ExceptionRecord 2. CONTEXT

————————————————————————————————————————————————————————————————————

|

|

|——>> C++ 语言中使用 throw(抛出)异常 、try{}catch(){}....(一个或多个catch子句) 捕获异常,处理异常代码。

二、 C++ 异常的规则

C++ 和 JAVA 中我们称之为抛出异常 throw

C++ 异常处理中包括:

· throw表达式(throw expression) 抛出异常

· 错误检测部分使用这种表达式来说明遇到了不可处理的错误。可以说,throw引发(raise)了异常条件。

· 使用头文件<stdexcept>

· try块(try block),错误处理部分使用它来处理异常。

try语句块以try关键字开始,并以一个或多个catch子句(catch clause) 结束。

· catch(捕获异常)

在try块中执行的代码所抛出(throw)的异常,通常会被其中一个catch子句处理。

由于catch子句处理异常,所以catch子句也称为异常处理代码(handler)。

· 由标准库定义的一组异常类(exception class),用来在throw 和相应的catch 之间传递有关的错误信息。

三、标准库异常语句

1. throw表达式

>> syntax

throw表达式: 以关键字throw 开始, 后面跟随表达式,然后以分号结束,就形成了表达式语句。

throw表达式的类型决定了所抛出异常的类型。

示例:

#include<iostream>

using std::cin;

using std::cout;

using std::endl;

#include<string>

using std::string;

#inculde<stdexcept>

using std::runtime_error;

string mstr , mstr2 ;

int main()

{

cout<<"please enter you name! your age! your book live\n";

cin>>mstr>>mstr2;

if(!mstr.same_isbn(mstr2))

throw runtime_error("Data must refer to same ISBN");

cout<<mstr+mstr2<<endl;

system("PAUSE");

return 0;

}

>> 使用throw 抛出异常,由catch捕获异常,由跟在catch后面的异常处理代码处理异常。

2. try 块

try块的通用语法形式是:

try{

program-statements // 形成程序的正常逻辑;可以包含任意C++ 语句,变量声明(同样引入局部代码块作用域)

}catch(exception-specifier){

handler-statements

}catch(exception-specifier){

handler-statements

}catch(exception-specifier){

handler-statements

}// .....

try 块以关键字try开始,后面是用花括号括起来的语句序列块。

try 块后面是一个或多个catch子句。

注意:

· try 的program-statements 可以是任意C++ 语句,包括变量声明定义,而且同样引入局部作用域,而且在try块和catch子句中定义的变量不能在try外面引用。

每个catch子句包含三部分:

1. 关键字catch

2. 圆括号内单个类型或者单个对象的声明——称为 异常说明符(exception specifier)

3. 以及通常用花括号括起来的语句块。

如果选择了一个catch 子句来处理异常,则执行相关的语句。一旦catch 子句执行结束,程序流程立即继续执行紧随着最后一个catch子句的语句。

2. 多层嵌套try块——致使函数在寻找处理代码的过程中退出:

例如:

一个函数包含try块,然后调用了其他的函数,其他的函数包含try块,且有调用了其他函数。在此时抛出异常,而查找异常处理程序,需要通过catch的异常说明符来进行查找匹配,在throw 抛出异常时由于嵌套调用已经经过了多个try块,这时超找处理函数需要向后超找,也就是说当前的try块没有对应的的异常处理的函数,则退出当前函数,进入上一个调用者函数,从中查找异常处理代码,如果依然不存在处理代码,则退出所在函数,查找上个调用函数的catch子句。

周而复始,如果一直没有找到处理异常的代码catch语句遍历了都没有,则调用标准库函数(定义在exception头文件中的)terminated,这个标准库函数依赖于系统,它的执行将导致程序非正常退出。

注意: 在程序中出现的异常,如果没有经try块定义,则偶以相同的方式来处理:因为如果没有任何try块,也就没有捕获异常的catch子句(就没有处理异常的代码)。

此时,如果发生了异常,系统将自动调用 terminated终止程序的执行。

四、 C++ 标准异常

C++ 标准库定义了一组类,用于报告在标准库中的函数遇到的问题,程序员可以在自己编写的程序中使用这些标准异常类。

标准异常类定义在四个头文件中:

<stdexcept>

定义了几种常见的异常类。

<exception>

头文件定义了最常见的异常类,它的类名是exception。这个类只通知异常的产生,不会提供更多的信息。

<new>

定义了bad_alloc 异常类型,提供因无法分配内存而由new抛出的异常。

<type_info>

type_info 头文件定义了bad_cast异常类型。

标准库异常类的作用:

标准库异常类只提供很少的操作,包括创建、复制异常类型对象以及异常类型对象的赋值。

exception 、 bad_alloc 以及bad_cast 类型只定义了默认构造函数,无法在创建这些类型的对象时为他们提供初值。

其他的异常类型则只定义了一个使用string 初始化式的构造函数。当需要定义这些异常类型的对象时,必须提供一个string参数。

string 初始化式用于为所发生的错误提供更多的信息。

异常类型定义的操作:

异常类型只定义了一个名为what 的操作 ,这个函数不需要任何参数,并且返回const char* 类型的值。它返回的指针指向一个C风格字符串。 使用C风格字符串目的是为所抛出的异常提供更详细的文字描述。

what 函数所返回的指针 指向C语言风格的字符数组的内容,这个数组的内容依赖于异常对象的类型。对于使用string初始化式的异常类型,what 函数将返回该string 作为。

对于其他异常类型,返回的值根据编译器的变化而不同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: