C++中异常处理的语法

来源:互联网 发布:淘宝的营销词 编辑:程序博客网 时间:2024/06/05 14:24

   关键字        1、 try    2、 catch    3、 throw    其中关键字try表示定义一个受到监控、受到保护的程序代码块;关键字catch与try遥相呼应,定义当try   block(受监控的程序块)出现异常时,错误处理的程序模块,并且每个catch   block都带一个参数(类似于函数定义时的数那样),这个参数的数据类型用于异常对象的数据类型进行匹配;而throw则是检测到一个异常错误发生后向 外抛出一个异常事件,通知对应的catch程序块执行对应的错误处理。      语法    1、 还是给一个例子吧!如下:   int   main()      {       cout   <<   "In   main."   <<   endl;      //定义一个try   block,它是用一对花括号{}所括起来的块作用域的代码块      try     {      cout   <<   "在   try   block   中,   准备抛出一个异常."   <<   endl;      //这里抛出一个异常(其中异常对象的数据类型是int,值为1)    //由于在try   block中的代码是受到监控保护的,所以抛出异常后,程序的      //控制流便转到随后的catch   block中      throw   1;      cout   <<   "在   try   block   中,   由于前面抛出了一个异常,因此这里的 代码是不会得以执行到的"   <<   endl;       }       //这里必须相对应地,至少定义一个catch   block,同样它也是用花括号括 起来的       catch(   int&   value   )      {       cout   <<   "在   catch   block   中,   处理异常错误。异常对象value的值 为:"<<   value   <<   endl;       }       cout   <<   "Back   in   main.   Execution   resumes   here."   <<   endl;        return   0;       }    2、语法很简单吧!的确如此。另外一个try   block可以有多个对应的catch   block,可为什么要多个catch   block呢?这是因为每个catch   block匹配一种类型的异常错误对象的处理,多个catch   block呢就可以针对不同的异常错误类型分别处理。毕竟异常错误也是分级别的呀!有致命的、有一般的、有警告的,甚至还有的只是事件通知。例子如下:   int   main()     {    try     {      cout   <<   "在   try   block   中,   准备抛出一个int数据类型的异常."   <<   endl;     throw   1;      cout   <<   "在   try   block   中,   准备抛出一个double数据类型的异常."   <<   endl;     throw   0.5;     }      catch(   int&   value   )     {      cout   <<   "在   catch   block   中,   int数据类型处理异常错误。”<<   endl;      }      catch(   double&   d_value   )     {      cout   <<   "在   catch   block   中,   double数据类型处理异常错误。”<<   endl;     }      return   0;     }    3、一个函数中可以有多个trycatch结构块,例子如下:     int   main()     {     try     {      cout   <<   "在   try   block   中,   准备抛出一个int数据类型的异常."   <<   endl;     throw   1;     }      catch(   int&   value   )     {      cout   <<   "在   catch   block   中,   int数据类型处理异常错误。”<<   endl;     }      //这里是二个trycatch结构块,当然也可以有第三、第四个,甚至更多     try     {      cout   <<   "在   try   block   中,   准备抛出一个double数据类型的异常."   <<   endl;     throw   0.5;     }      catch(   double&   d_value   )     {      cout   <<   "在   catch   block   中,   double数据类型处理异常错误。”<<   endl;      }      return   0;     }        4、上面提到一个try   block可以有多个对应的catch   block,这样便于不同的异常错误分类处理,其实这只是异常错误分类处理的方法之一(暂且把它叫做横向展开的吧!)。另外还有一种就是纵向的,也即是分 层的、trycatch块是可以嵌套的,当在低层的trycatch结构块中不能匹配到相同类型的catch   block时,它就会到上层的trycatch块中去寻找匹配到正确的catch   block异常处理模块。例程如下:     int   main()     {     try     {      //这里是嵌套的trycatch结构块    try   {      cout   <<   "在   try   block   中,   准备抛出一个int数据类型的异常."   <<   endl;     throw   1;     }      catch(   int&   value   )     {      cout   <<   "在   catch   block   中,   int数据类型处理异常错误。”<<   endl;      }      cout   <<   "在   try   block   中,   准备抛出一个double数据类型的异常."   <<   endl;     throw   0.5;     }      catch(   double&   d_value   )   {      cout   <<   "在   catch   block   中,   double数据类型处理异常错误。”<<   endl;     }      return   0;     }     5、讲到是trycatch块是可以嵌套分层的,并且通过异常对象的数据类型来进行匹配,以找到正确的catch   block异常错误处理代码。这里就不得不详细叙述一下通过异常对象的数据类型来进行匹配找到正确的catch   block的过程。       (1)   首先在抛出异常的trycatch块中查找catch   block,按顺序先是与第一个catch   block块匹配,如果抛出的异常对象的数据类型与catch   block中传入的异常对象的临时变量(就是catch语句后面参数)的数据类型完全相同,或是它的子类型对象,则匹配成功,进入到catch   block中执行;否则到二步;       (2)   如果有二个或更多的catch   block,则继续查找匹配第二个、第三个,乃至最后一个catch   block,如匹配成功,则进入到对应的catch   block中执行;否则到三步;        (3)   返回到上一级的trycatch块中,按规则继续查找对应的catch   block。如果找到, 进入到对应的catch   block中执行;否则到四步;  (4)   再到上上级的trycatch块中,如此不断递归,直到匹配到顶级的trycatch块中的最后一个catch   block,如果找到,进入到对应的catch   block中执行;否则程序将会执行terminate()退出。    另外分层嵌套的trycatch块是可以跨越函数作用域的,例程如下:     void   Func()   throw()     {      //这里实际上也是嵌套在里层的trycatch结构块     try     {      cout   <<   "在   try   block   中,   准备抛出一个int数据类型的异常."   <<   endl;     //由于这个trycatch块中不能找到匹配的catch   block,所以     //它会继续查找到调用这个函数的上层函数的trycatch块。     throw   1;     }      catch(   float&   value   )     {      cout   <<   "在   catch   block   中,   int数据类型处理异常错误。”<<   endl;     }     }      int   main()     {       try       {      Func();      cout   <<   "在   try   block   中,   准备抛出一个double数据类型的异常."   <<   endl;      throw   0.5;     }      catch(   double&   d_value   )     {      cout   <<   "在   catch   block   中,   double数据类型处理异常错误。”<<   endl;      }      catch(   int&   value   )   {      //这个例子中,Func()函数中抛出的异常会在此被处理      cout   <<   "在   catch   block   中,   int数据类型处理异常错误。”<<   endl;      }      return   0;     }    6、刚才提到,嵌套的trycatch块是可以跨越函数作用域的,其实这里面还有另外一层涵义,就是抛出异常对象的函数中并不一定必须存在 trycatch块,它可以是调用这个函数的 上层函数中存在trycatch块,这样这个函数的代码也同样是受保护、受监控的代码;当然即便是上层调用函 数不存在trycatch块,也只是不能找到处理这类异常对象错误处理的catch   block而已,例程如下:    void   Func()   throw()     {      //这里实际上也是嵌套在里层的trycatch结构块      //由于这个函数中是没有trycatch块的,所以它会查找到调用这个函数的上     //层函数的trycatch块中。      throw   1;     }   int   main()      {     try     {      //调用函数,注意这个函数里面抛出一个异常对象     Func();      cout   <<   "在   try   block   中,   准备抛出一个double数据类型的异常."   <<   endl;      throw   0.5;     }      catch(   double&   d_value   )     {      cout   <<   "在   catch   block   中,   double数据类型处理异常错误。”<<   endl;      }      catch(   int&   value   )     {      //这个例子中,Func()函数中抛出的异常会在此被处理    cout   <<   "在   catch   block   中,   int数据类型处理异常错误。”<<   endl;     }      //如果这里调用这个函数,那么由于main()已经是调用栈的顶层函数,因此不能找      //到对应的catch   block,所以程序会执行terminate()退出。   Func();    //   [特别提示]:在C++标准中规定,可以在程序任何地方throw一个异常对象,     //   并不要求一定只能是在受到try   block监控保护的作用域中才能抛出异常,但   //   如果在程序中出现了抛出的找不到对应catch   block的异常对象时,C++标   //   准中规定要求系统必须执行terminate()来终止程序。  //   因此这个例程是可以编译通过的,但运行时却会异常终止。这往往给软件 //   系统带来了不安全性。与此形成对比的是java中提供的异常处理模型却是不 //   永许出现这样的找不到对应catch   block的异常对象,它在编译时就给出错误 //   提示,所以java中提供的异常处理模型往往比C++要更完善,后面的章节      //   会进一步对这两种异常处理模型进行一个详细的分析比较。   return   0;      }

 

 

try是c++异常处理结构try_catch throw 的一部分

抛出异常(也称为抛弃异常)即检测是否产生异常,在C++中,其采用throw语句来实现,如果检测到产生异常,则抛出异常。该语句的格式为:
throw 表达式;
如果在try语句块的程序段中(包括在其中调用的函数)发现了异常,且抛弃了该异常,则这个异常就可以被try语句块后的某个catch语句所捕获并处理,捕获和处理的条件是被抛弃的异常的类型与catch语句的异常类型相匹配。由于C++使用数据类型来区分不同的异常,因此在判断异常时,throw语句中的表达式的值就没有实际意义,而表达式的类型就特别重要。
【范例20-2】处理除数为0的异常。该范例将上述除数为0的异常可以用try/catch语句来捕获异常,并使用throw语句来抛出异常,从而实现异常处理,实现代码如代码清单20-2所示。
代码清单20-2
1 #include<iostream.h> //包含头文件
2 #include<stdlib.h>
3 double fuc(double x, double y) //定义函数
4 {
5 if(y==0)
6 {
7 throw y; //除数为0,抛出异常
8 }
9 return x/y; //否则返回两个数的商
10 }
11 void main()
12 {
13 double res;
14 try //定义异常
15 {
16 res=fuc(2,3);
17 cout<<"The result of x/y is : "<<res<<endl;
18 res=fuc(4,0); //出现异常
19 }
20 catch(double) //捕获并处理异常
21 {
22 cerr<<"error of dividing zero.\n";
23 exit(1); //异常退出程序
24 }
25 }

0 0