C++教程5之异常处理
第V章
Exception handling 异常处理
异常是正常程序流中意想不到的中断。在C和其他编程语言里,有几种方法来处理这样不规则的情形:从简单发出一个警告到后退到一个错误处理器以及用setjmp()和longjmp()实现的复杂机制。本章描述C++对于异常处理的方案。
V-1 Handling exceptions in C
在C里实现异常处理有下列几种方法:
1、Exit
立即使用exit()函数终止程序执行。这是最糟糕的处理异常方式
2、发出一个警告
一个函数可以在程序里发现问题,然后给出一条信息,比如,程序员增加一些条件检测来捕捉微小的问题。这是个没什么害处的动作。
3、实现fallback,回撤到函数调用上层,进行错误处理
另一个比较复杂的方式可以是停止函数执行,把问题委派给(经由一段错误代码)调用者函数(称之为fallback error handling)。和错误代码一起,也可以返回数据信息,这让调用者函数可以重新启动运行。调用者函数可以决定做同样的动作等等。这方法的缺点是为了能传递数据信息给它们的调用者需要增加函数接口。而且,要返回多层才能继续执行。
4、保存stack内容
可以使用setjmp()和longjmp()函数把执行动作移到另一个执行深度(指在堆栈不同点移动),对于stack上下文,这有点类似goto语句。因为这个原因,所以不推荐使用这方法。Linux手册页注解:setjmp()/longjmp()程序很难理解、难以维护,如果有替代方法,尽量不要用这方法。
V-2 The C++ method
上面提及的方法在C++中依然可用。然而这些异常可以经由异常机制()用更统一的(且更强大的)方式处理。后面一些小节讨论了C++的异常用法。
V-2.1 Syntax
为异常处理增加3个关键字
1. try {...}
try代码块包含可能导致产生(C++中的术语叫抛出thrown)异常的语句。
2. throw expression
throw关键字通过抛出作为异常的表达式值产生(raise)一个异常。throw因该在try代码块里执行、或者在一个函数里执行(在函数从try代码块里调用)。
3. catch(expression){...}
catch代码块执行某个异常处理,该异常类型与expression匹配。必须跟在try代码块后面
V-2.2 Example: Safe division of integers
下面例子展示如何使用异常来避免两个整数a和b相除时丢失精度。算法的思想是如果a%b等于0,那么整数除法是安全的。否则,应该采用实数除法,这种情形下,我们把参数传给一个函数执行实数除法。类实现如下:
- #include
- // will be used for raising the exception
- class loss_of_precision_in_division
- {
- public:
- loss_of_precision_in_division(int x, int y)
- { a = x; b = y; }
- int get_a() const { return a; }
- int get_b() const { return b; }
- private:
- int a, b;
- };
这样可以写一个安全的除法函数:
- int safe_divide(int a, int b)
- {
- if (a % b == 0)
- return a / b;
- else
- throw loss_of_precision_in_division(a, b);
- }
主程序如下:
- int main()
- {
- double d;
- int a, b;
- // read a and b
- cin >> a >> b;
- try
- {
- d = safe_divide(a, b);
- }
- catch (loss_of_precision_in_division x)
- {
- cout << "loss of precision in division!" << d =" double(x.get_a())">
- class odd { };
- class even { };
- int main()
- {
- int a;
- cin >> a;
- try
- {
- if (a < a =" -a;" 2 ="="">
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
