异常处理:
异常处理的方式:
示例程序:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 double divide(double a, double b, int* valid) 7 { 8 const double delta = 0.000000000000001; 9 double ret = 0; 10 11 if( !((-delta < b) && (b < delta)) ) 12 { 13 ret = a / b; 14 15 *valid = 1; 16 } 17 else 18 { 19 *valid = 0; 20 } 21 22 return ret; 23 } 24 25 int main(int argc, char *argv[]) 26 { 27 int valid = 0; 28 double r = divide(1, 0, &valid); 29 30 if( valid ) 31 { 32 cout << "r = " << r << endl; 33 } 34 else 35 { 36 cout << "Divided by zero..." << endl; 37 } 38 39 return 0; 40 }
运行结果如下:
缺陷:
我们需要统一加减乘除的调用方法,将除法改为两个参数,而且还有异常处理的功能。
改进方法:
除法操作异常处理优化:
1 #include <iostream> 2 #include <string> 3 #include <csetjmp> 4 5 using namespace std; 6 7 static jmp_buf env; 8 9 double divide(double a, double b) 10 { 11 const double delta = 0.000000000000001; 12 double ret = 0; 13 14 if( !((-delta < b) && (b < delta)) ) 15 { 16 ret = a / b; 17 } 18 else 19 { 20 longjmp(env, 1); 21 } 22 23 return ret; 24 } 25 26 int main(int argc, char *argv[]) 27 { 28 if( setjmp(env) == 0 ) 29 { 30 double r = divide(1, 1); 31 32 cout << "r = " << r << endl; 33 } 34 else 35 { 36 cout << "Divided by zero..." << endl; 37 } 38 39 return 0; 40 }
程序先执行28行,这是直接执行setjmp,就直接将程序执行上下文保存在env中,然后条件判断为真,然后执行第30行的除法,调用到了divide函数,当除数为0时,这时就会执行到divide的else分支,这时遇到一个longjmp,longjmp根据env恢复程序执行上下文,使得程序回到第28行的状态(也就是从第28行出来),使程序从setjmp返回的地方开始执行,并且将返回值设置为了1,这时第28行的判断就不为真了,于是就执行到了36行的else分支了。
运行结果如下:
这是一种优雅的处理方式,但是理解起来较困难。
缺陷:
小结: