第十课 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语句。

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

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9498609.html