对码当歌,猿生几何?

C++语法小记---异常处理

异常处理(C语言)

  • 异常是对代码中可以预知的问题进行处理;代码中不可以预知的问题叫Bug;

  • if () { ... } else { ... }

  • setjmp和longjmp

 1 #include <stdio.h> 2 #include <setjmp.h> 3  4 jmp_buf env = {0}; 5  6 int divid(int a, int b) 7 { 8     if(b == 0) 9     {10         longjmp(env, 1);   //2. 恢复保存的上下文,并设置setjmp的返回值(第二个参数)11     }12     else13     {14         return a / b;15     }16 }17 18 int main()19 {20     if(setjmp(env) == 0)   //1. 保存当前上下文,返回为0;21                            //3. 调用longjmp后,返回此处,返回值为longjmp设置的返回值22     {23         printf("divid(1, 0) = %d", divid(1, 0));24     }25     else26     {27         printf("Unexpected!!");28     }29     30     return 0; 
31 }

 

异常处理(C++语言)

  • C++在语言层面提供异常的处理机制

  • 异常的抛出和处理分开,更合理、灵活

  • try { ... } catch { ... }

  • 使用throw关键字抛出异常,抛出的异常可以是任何类型,基础类型、类类型以及自定义类型都可以

  • 异常抛出后,会沿着函数调用的顺序向上依次寻找捕捉的地方,如果找不到,程序终止;如果找到(匹配到catch),进入catch进行处理,程序不终止

  • 一个try可以接续多个catch,catch的匹配规则如下:

    • 每个异常只能被一个catch分支处理

    • 匹配的过程从上至下依次匹配

    • 匹配的规则类似函数调用的过程,但是不进行隐式类型转换,严格参数匹配

    • 抛出的异常会有用于初始化catch中的参数

    • 基类可以匹配子类的异常

    • 不一定要使用C++库中提供的异常,可以使用自定义的异常

    • 一般使用可变参数作为最后一个catch分支,做楼底处理

  • try { ... } catch { ... }可以嵌套,工程意义是对异常进行重新解释,做兼容处理

 1 #include <iostream> 2 #include <string> 3  4 using namespace std; 5  6 void func()      //嵌套,对异常进行重新封装解释 7 { 8     try 9     {10         throw 2;11     }12     catch(int i)13     {14         if(i == 2)15         {16             throw string("error no 2");17         }18     }19 }20 21 int main()22 {23     try24     {25         throw 1;26     }27     catch(int e)28     {29         cout<< "catch(int e)" << endl;30     }31     catch(...)32     {33         cout<< "catch(...)" <<endl;34     }35     36     try37     {38         func();39     }40     catch(string e)41     {42         cout<< e <<endl;43     }44     45     return 0; 
46 }