zoukankan      html  css  js  c++  java
  • 第十课 C++异常简介

      异常不是错误,异常是程序中可预料到的另一条执行分支,是可预见的。错误是不可预料的。

    C++内置了异常处理的语法元素try...catch...,如下:

    C++通过throw语句抛出异常信息:

    上图中throw 0抛出异常后,程序就立即返回了。return代表正常的返回,throw代表异常的返回值。

    C++异常处理分析:

      throw抛出的异常必须被catch处理

        当前函数能够处理异常,程序继续往下执行

        当前函数无法处理异常,则函数停止执行并返回

    未被处理的异常则顺着函数调用栈向上传播:

    异常的示例程序如下:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 double divide(double a, double b)
     6 {
     7     const double delta = 0.000000000000001;
     8     double ret = 0;
     9 
    10     if( !((-delta < b) && (b < delta)) ) {
    11         ret = a / b;
    12     }
    13     else {
    14         throw 0;   // 产生除 0 异常
    15     }
    16 
    17     return ret;
    18 }
    19 
    20 int main()
    21 {
    22     cout << "main() begin " << endl;
    23 
    24     try
    25     {
    26         divide(1, 0);
    27     }
    28     catch(...)
    29     {
    30         cout << "Divided by zero" << endl;
    31     }
    32 
    33     cout << "main() end " << endl;
    34     return 0;
    35 }

    执行结果如下:

    26行的异常被28行的catch捕获,处理完这个异常之后,程序继续向下执行,33行成功打印出信息。

    更改程序如下:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 double divide(double a, double b)
     6 {
     7     const double delta = 0.000000000000001;
     8     double ret = 0;
     9 
    10     if( !((-delta < b) && (b < delta)) ) {
    11         ret = a / b;
    12     }
    13     else {
    14         throw 0;   // 产生除 0 异常
    15     }
    16 
    17     return ret;
    18 }
    19 
    20 int main()
    21 {
    22     cout << "main() begin " << endl;
    23 
    24     try
    25     {
    26         int c = divide(1, 0);
    27 
    28         cout << "c = " << c << endl;
    29     }
    30     catch(...)
    31     {
    32         cout << "Divided by zero" << endl;
    33     }
    34 
    35     cout << "main() end " << endl;
    36     return 0;
    37 }

    执行结果如下:

    可以看到第28行的打印没有输出。

     如果try中的语句没有发生异常,catch中的语句是不会执行的。

    同一个try语句可以跟上多个catch语句:

    异常处理的匹配规则:

    捕捉异常的示例程序:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 double divide(double a, double b)
     6 {
     7     const double delta = 0.000000000000001;
     8     double ret = 0;
     9 
    10     if( !((-delta < b) && (b < delta)) ) {
    11         ret = a / b;
    12     }
    13     else {
    14         throw 0;   // 产生除 0 异常
    15     }
    16 
    17     return ret;
    18 }
    19 
    20 void Demo1()
    21 {
    22     try
    23     {
    24         throw 'c';
    25     }
    26     catch(int i)
    27     {
    28         cout << "catch (int i) " << endl;
    29     }
    30     catch(double d)
    31     {
    32         cout << "catch(double d)" << endl;
    33     }
    34     catch(char c)
    35     {
    36         cout << "catch(char c)" << endl;
    37     }
    38 }
    39 
    40 int main()
    41 {
    42     cout << "main() begin " << endl;
    43 
    44     try
    45     {
    46         int c = divide(1, 0);
    47 
    48         cout << "c = " << c << endl;
    49     }
    50     catch(...)
    51     {
    52         cout << "Divided by zero" << endl;
    53     }
    54 
    55     Demo1();
    56 
    57     cout << "main() end " << endl;
    58     return 0;
    59 }

    执行结果如下:

    异常捕捉示例程序:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 double divide(double a, double b)
     6 {
     7     const double delta = 0.000000000000001;
     8     double ret = 0;
     9 
    10     if( !((-delta < b) && (b < delta)) ) {
    11         ret = a / b;
    12     }
    13     else {
    14         throw 0;   // 产生除 0 异常
    15     }
    16 
    17     return ret;
    18 }
    19 
    20 void Demo1()
    21 {
    22     try
    23     {
    24         throw 'c';
    25     }
    26     catch(int i)
    27     {
    28         cout << "catch (int i) " << endl;
    29     }
    30     catch(double d)
    31     {
    32         cout << "catch(double d)" << endl;
    33     }
    34     catch(char c)
    35     {
    36         cout << "catch(char c)" << endl;
    37     }
    38 }
    39 
    40 void Demo2()
    41 {
    42     throw "D.T.Software";   // const char*
    43 }
    44 
    45 int main()
    46 {
    47     cout << "main() begin" << endl;
    48 
    49     try
    50     {
    51         double c = divide(1, 1);
    52 
    53         cout << "c = " << c << endl;
    54     }
    55     catch(...)
    56     {
    57         cout << "Divided by zero..."  << endl;
    58     }
    59 
    60     Demo1();
    61 
    62     try
    63     {
    64         Demo2();
    65     }
    66     catch(char* c)
    67     {
    68         cout << "catch(char* c)" << endl;
    69     }
    70     catch(const char* cc)
    71     {
    72         cout << "catch(char* cc)" << endl;
    73     }
    74     catch(...)
    75     {
    76         cout << "catch(...)" << endl;
    77     }
    78 
    79     cout << "main() end" << endl;
    80 
    81     return 0;
    82 }

    执行结果如下:

    catch捕捉异常时,是类型严格匹配的,不会进行类型转换。字符串是const char*类型。

     小结:

      C++中直接支持异常处理的概念。

      try...catch...是C++中异常处理的专用语句。

      try语句处理正常代码逻辑,catch语句处理异常情况。

      同一个try语句可以跟上多个catch语句。

      异常处理必须严格匹配,不进行任何的类型转换。

  • 相关阅读:
    nodejs MYSQL数据库执行多表查询
    【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演
    【BZOJ2693】jzptab 莫比乌斯反演
    【BZOJ2154】Crash的数字表格 莫比乌斯反演
    【BZOJ2242】[SDOI2011]计算器 BSGS
    【BZOJ2005】[Noi2010]能量采集 欧拉函数
    【BZOJ1408】[Noi2002]Robot DP+数学
    【BZOJ2045】双亲数 莫比乌斯反演
    【BZOJ2186】[Sdoi2008]沙拉公主的困惑 线性筛素数
    【BZOJ4176】Lucas的数论 莫比乌斯反演
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9498609.html
Copyright © 2011-2022 走看看