的。 .异常不能被线程忽略,必须被处理。 .未处理的异常会使进程结束,而不仅仅是结束线程。 .异常出来在释放栈时会释放所有的栈对象,避免了资源的漏洞。 .异常处理需要大量的额外操作,使得它不适于经常运行的代码。 .可以抛出任何类型的异常对象,除了整数。
如果正确执行,异常处理有下面的特性: .异常是不是正常的运行结果,是特殊情况。 .异常在返回值无效的情况下使用。 .异常是可靠的,不
可能被忽略。 .异常简化了错误处理,简化了程序代码,使错误处理更加方便。 Visual C++的默认情况下,在调试版本中处理异常,而在发布版本中并不进行处理。由于异常也是错误,Windows 异常码 采用了同 Windows 错误码一样的位映射模式,为一个 32 位的值,这些码由 Microsoft 定义,任何异常码的最高四位总是 1100 (二进制) ,即十六进制里的 0xC。 2、Windows 结构异常和 C++异常 Windows 结构异常作为硬件异常(如访问非法或被零除)或操作系统异常的结果被抛出,C++异常只能由 throw 语句抛出。 Windows 结构异常处理不能处理对象的解析,因此你应该在 C++程序中一直使用 C++异常。然而,C++异常不能处理硬件和操 作
系统异常,你的程序需要将结构异常转化为 C++异常。C++异常并不直接从你的程序代码中抛出而是从 C++运行库中抛出, 因此你需要调用栈窗口来返回你的代码。为了正确处理硬件和操作系统异常,你可以创建自己的异常类并使用_set_se_translator 函数安装一个结构异常向 C++异常的转化器,但不要捕获那些不能恢复所产生问题的转化后的结构异常。 3、MFC 中的异常 在 MFC 中,所有的异常对象都是从 CException 基类(它有使用起来非常方便的 GetErrorMessage 和 ReportError 成员函数) 中派生来的。 大多数的 MFC 异常对象都是动态分配的, 而且当它们被捕获时, 必须被删除, 而没有被捕获的 MFC 异常由 MFC 本身在 AfxCallWndProc 函数中捕获并删除。 4、异常的开销 当抛出 C++异常时, 函数调用链将从此回溯搜索, 寻找可以处理抛出这类异常的处理器。 若没找到, 进程结束。 如果找到, 调用栈将被释放,所有的自动(局部)变量也将释放,然后栈将被整理为异常处理器的上下文相关设备。因此异常开销由一个 异常处理器目录和一个活动的自动变量表(它需要额外的代码、内存,而且不论异常是否抛出,都会运行) ,还得加上函数调用 链的
搜索、自动变量的解析和栈的调整(它只在抛出异常的时候需要执行)组成。 5、异常策略 (1)抛出时机 抛出异常的时机应该是一个函数发现一个错误,如果没有一些特殊的操作,该错误能阻止程序正常的运行,而这种操作它 自己不能完成,或是在函数不可能有返回值的时候。 使用异常处理更简单,更可靠,更有效,可以创建更健壮的代码。然而,应该只在意外的情况下使用异常处理。如果你认 为一个指针应该是空值,这种条件下就直接在代码中检查这个值,而不要使用异常。 (2)何时捕获 对于这个问题,有一些可能的标准: .当函数知道如何处理这个异常时。 .当这个函数可以合理地处理这个异常而高级的函数不知
道如何处理时。 .当抛出异常可能使进程崩溃时。 .当函数可以继续执行它的任务时。 .当需要整理分配好的资源时。 异常处理的一个缺点是它可能导致资源的泄露。因此,防止资源泄露更应该是保持程序异常安全的一部分。栈释放时会自 动整理局部变量, 但不包括动态分配的变量。 可以使用智能(smart)指针来保护你的代码在存在异常的情况下不会产生资源泄漏。 (3)怎样捕获 .非 MFC 的 C++异常应该通过引用来捕获。使用引用捕获异常不需要删除异常对象(因为使用引用捕获的异常会在栈中传 送) ,而且它保留了多态性(因此你捕获的异常对象正是你抛出的异常对象) 。 .MFC 异常应