Handling Errors Exceptionally Well in C++
在C++中良好地捕获意外的错误
from:http://www.cprogramming.com/tutorial/exceptions.html
author:unknown
翻译:范晨鹏
One benefit of C++ over C is its exception handling system. An exception is a situation in which a program has an unexpected circumstance that the section of code containing the problem is not explicitly designed to handle. In C++, exception handling is useful because it makes it easy to separate the error handling code from the code written to handle the chores of the program. Doing so makes reading and writing the code easier.
C++的一个特性是它的异常捕获系统。异常 是程序的一个未曾预料到的环节,没有代码被明确地设计用来处理包含问题的代码片断。在C++中,异常处理是非常有用的。因为它使得错误处理代码从程序的正常代码中分离出来。从而使得代码容易书写并便于阅读。
Furthermore, exception handling in C++ propagates the exceptions up the stack; therefore, if there are several functions called, but only one function that needs to reliably deal with errors, the method C++ uses to handle exceptions means that it can easily handle those exceptions without any code in the intermediate functions. One consequence is that functions don't need to return error codes, freeing their return values for program logic.
而且,C++的异常捕获一直传达到栈中。因此,如果有一系列的函数调用,但是仅有一个函数需要进行错误处理,C++中使用的异常捕获意味着它可以很容易地来处理那些异常,而不需要在函数内部书写专门的代码。其影响是:函数不需要返回错误代码,这为程序逻辑解放了它们的返回值。
When errors occur, the function generating the error can 'throw' an exception. For example, take a sample function that does division:
错误发生的时候,产生错误的函数会“抛出”一个异常。以一个做除法运算的函数为例来说明:
const int DivideByZero = 10;
//....
double divide(double x, double y)
{
if(y==0)
{
throw DivideByZero;
}
return x/y;
}
The function will throw DivideByZero as an exception that can then be caught by an exception-handling catch statement that catches exceptions of type int. The necessary construction for catching exceptions is a try catch system. If you wish to have your program check for exceptions, you must enclose the code that may have exceptions thrown in a try block. For example:
这个函数会返回“除数为0”的错误。这个异常随后会被专门捕获int型异常的异常捕获语句捕获。捕获异常必须的构件是一个try catch系统。如果你希望你的程序接收异常检查,你必须将可能有异常捕获的代码包含在一个try块中。例如:
try
{
divide(10, 0);
}
catch(int i)
{
if(i==DivideByZero)
{
cerr<<"Divide by zero error";
}
}
The catch statement catches exceptions that are of the proper type. You can, for example, throw objects of a class to differentiate between several different exceptions. As well, once a catch statement is executed, the program continues to run from the end of the catch.
catch
catch语句捕获特定类型的异常。例如,你可以抛出一个类的几个对象来区分一些不同的异常。同时,一旦执行了一个catch语句,程序会从catch块的后面继续执行。
It is often more useful for you to create a class that stores information on exceptions as they occur. For example, it would be more useful if you had a class to handle exceptions.
创建一个类来保存错误发生时的信息是常常是很有用的。例如,如果你用一个类来处理异常:
class DivideByZero
{
public:
double divisor;
DivideByZero(double x);
};
DivideByZero::DivideByZero(double x) : divisor(x)
{}
int divide(int x, int y)
{
if(y==0)
{
throw DivideByZero(x);
}
}
try
{
divide(12, 0);
}
catch (DivideByZero divZero)
{
cerr<<"Attempted to divide "<<divZero.divisor<<" by zero";
}
f you wish to catch more than one possible exception, you can specify separate catch blocks for each type of exception. It's also possible to have a general exception handler that will respond to any thrown exception. To use it, simply use catch(...) for the catch statement and print a general warning of some kind.
如果你想捕获超过一个可能的异常,你可以为每个类型的异常指定独立的catch块。还可用一个通用的异常句柄来响应抛出的任何异常。要使用它,只需要为catch语句使用catch(...)来打印一个通用的警告语句或使用类似的处理方式。
The handy thing to remember about exception handling is that the errors can be handled outside of the regular code. This means that it is easier to structure the program code, and it makes dealing with errors more centralized. Finally, because the exception is passed back up the stack of calling functions, you can handle errors at any place you choose.
关于异常捕获顺便要提及的是:错误可以在正常代码之外被处理。这意味着很容易实现结构化的程序代码,而且它使得错误处理更集中。最后,因为异常被传回一直到主调函数的栈,你可以在(被调用函数)的任何地方捕获错误。
In C, you might see some error handling code to free memory and close files repeated five or or six times, once for each possible error. A solution some programmers prefered was to use a goto statement that jumped all the way to the cleanup code. Now, you can just surround your code with a try-catch block and handle any cleanup following the catch (possibly with an additional copy of your cleanup routine inside the catch block if you intend to throw the exception again to alert the calling function of an error).
在C中,你可能会看到一些错误捕获代码,这些代码用来释放内存和关闭文件。它们被重复若干次,在每一个可能发生错误的地方。一些程序员偏爱的一种解决方法是使用goto语句。goto语句可以直接跳到执行清除操作的代码部分。现在,你可以仅仅把你的代码包围在一个try-catch块中并在catch之后执行一个清除操作。(可能要在catch块中保存你的清理机制的一份拷备,如果你愿意将异常再次抛出以通知主调函数一个错误。)