目录
基本实现
主要通过三个关键字实现try,throw,catch
其中try为代码块检测,在try的块内抛出throw异常(当然也可以不在try块内抛出)。再由catch捕获异常分别执行不同异常的处理方式
try{ //语句块 throw1(某一类型的数据) throw2(某一数据类型) } catch(参数声明1){ 异常处理语句块1 } cach(参数声明2){ 异常处理语句块2 } ... cach(参数声明n){ 异常处理语句块n } catch(...){ 异常处理语句块n+1 }
注(1)catch是通过throw抛出不同的数据类型来进行相关的判断,而不是具体的数值行选择性执行的。其中...代表任意类型的错误,因而我们一般把...放到最后
(2)上述中如果其中某个throw抛出异常后,则会结束整个try块,也就是说try块这个throw后面的内容都不会执行。同样的某个catch捕获到异常后,则不会执行后面的catch。官方书籍这样描述:发生异常后,控制不会返回异常抛出点,而是由程序执行相应的catch块,然后跳过所有后续的catch块,再恢复执行。
举例如下:一个程序实现100以内数字的除法
#include <iostream> using namespace std; int main() { try {//代码保护片段 double a, b; cin >> a >> b; if (a > 100 || b > 100) throw 100; if (b == 0) throw 0.0; cout << a / b; } catch (int) { //捕获 cout << "the number is larger than 100"; } catch (double) { cout << "div 0"; } }
函数的异常处理
1、异常处理的分层
当我们不确定异常处理方式时,实际上我们可以把异常传递给上一层函数。比如main函数中有trigger()函数,当我们在trigger函数中抛出异常时,我们可以不做捕获处理,他会抛出异常给main函数,让main函数中的try块进行处理。
#include <iostream> using namespace std; void trigger(int x) { if (x == 1) { throw 0.0; //仅仅抛出处理,不必捕获 } } int main() { try { trigger(1); } catch (double) { cout << "you can not input 1" << endl; } cout << "the game is over!"; }
2、函数异常处理原型的申明
T是类型,parameterlist是参数表
指定异常 函数返回类型 函数名(参数表)throw (T1,T2...);
不抛出异常 函数返回类型 函数名 (参数表) throw();
抛出任意异常 函数返回类型 函数名(参数表) ;
#include <iostream> using namespace std; double calculate (int a, int b)throw(int, double) { if (a > 100 || b > 100) throw 100; if (b == 0) throw 0.0; return ( a / b); } int main() { int a, b; cin >> a >> b; try { calculate(a, b); } catch (int) { cout << "the number is larger than 100"; } catch (double) { cout << "div 0"; } }
3、构造函数异常处理
构造函数只进行抛出异常,而不进行catch捕获处理,而是由创建对象的函数去捕获处理。下面例子中是由main函数创建并catch捕获
#include <iostream> using namespace std; class calculate { public: int a; int b; calculate(int x, int y) { if (x > 100 || y > 100) { throw 100; } } }; int main() { int a, b; cin >> a >> b; try { calculate c1(a, b); } catch (int) { cout << "larger than 100"; } catch (...) { cout << "error!"; } }