C++ 捕获异常的一些规则:
1. 非MFC 的c++ 异常应该用过引用来捕获。使用引用来捕获异常不需要删除c++ 异常对象。因为使用引用捕获的异常对象会在栈中传递。而且保持了多态性,使得你捕获的异常正是你抛出的异常对象。使用指针捕获异常的话,需要你删除异常对象。使用值捕获的话,会导致对象的slicing 问题。更详细的信息见Effective C++ 第13条.
2. MFC 异常应该通过指针来捕获。因为它们通常从堆中分配。当你处理完异常之后,你需要调用Delete 成员函数。如下所示:
try
{
……
}
catch(CFileException *e)
{
// 异常处理
e->Delete();
}
因此,你不能用省略(catch (…)) 来捕获MFC 异常, 这通常会导致内存泄露。必须使用Delete 成员函数来删除异常,而不要使用delete ,因为一些MFC 异常作为静态对象创建。
一旦你捕获了异常,你可以通过执行下列典型动作组合来处理:
● 什么也不做
● 修改这个问题并重新执行代码
● 修改这个问题但不重新执行代码
● 如果用户需要的话,向用户显示出错信息。
● 如果出现的问题不是程序错误的话,输出一个跟踪的诊断消息。
● 如果出现的问题是一个程序错误,输出一个断言。
● 在日志文件里记录这个问题
● 如果异常是不可恢复的,终止进程的运行。
● 回收已分配的资源
● 重新抛出这个异常,或者抛出一个新的异常。
使用缺省捕获处理器(catch ( … ))
缺省捕获处理器可以捕获任何一个类型的异常。包括系统产生和程序产生的异常。其行为和switch 语句的default类似。这种处理方式功能很强大,使用也很方便。但是如果使用不当的话,是很有害的,因为你不能确定出现了什么问题。你能知道的就是在一些不知道的地方发生了你不知道的异常。因此,你没法知道在当前这个函数处理异常合适,还是在更高一级的函数处理合适,你也不知道究竟处理这个异常是不是合适。注意异常处理不当会破坏你的程序,或造成其他类型的破坏。所以你应该尽量不使用缺省的捕获异常处理器。
然而,下面两种情况下,使用缺省的捕获处理器是非常合适的:
● 处理器将重新抛出同一个异常,或抛出另一个异常。缺省捕获处理器经常用
于整理资源或重新抛出异常。
● 异常处理器在任何情况下结束进程。
在析构函数里不要抛出异常,这通常会造成进程终止。我已经调试过不只一次这种情况了。蹩脚的异常代码反而会把程序弄得更糟糕。
异常声明规范:
C++ 提供的异常声明规范:
// 正常的函数声明,可以抛出任意的异常
Void NormalFunction();
// 不抛出异常
Void NoThrowFunction throw();
// 只抛出指定异常
class ExceptionClass;
Void ThrowFunction() throw (ExceptionClass); // 包括ExceptionClass 的派生类型。