15.3.10 异常何时会迷失方向(2)
在这种情况下,行为与未捕获的异常极其类似。如果发生意外异常,程序将调用unexpected( )函数(您没有想到是unexpected( )函数吧?谁也想不到!)。这个函数将调用terminate( ),后者在默认情况下将调用abort( )。正如有一个可用于修改terminate( )的行为的set_terminate( )函数一样,也有一个可用于修改unexpected( )的行为的set_unexpected( )函数。这些新函数也是在头文件exception中声明的:
然而,与提供给set_terminate( )的函数的行为相比,提供给set_unexpected( )的函数的行为受到更严格的限制。具体地说,unexpected_handler函数可以:
通过调用terminate( )(默认行为)、abort( )或exit( )来终止程序;
引发异常。
引发异常(第二种选择)的结果取决于unexpected_handler函数所引发的异常以及引发意外异常的函数的异常规范:
如果新引发的异常与原来的异常规范匹配,则程序将从那里开始进行正常处理,即寻找与新引发的异常匹配的catch块。基本上,这种方法将用预期的异常取代意外异常;
如果新引发的异常与原来的异常规范不匹配,且异常规范中没有包括std ::bad_exception类型,则程序将调用terminate( )。bad_exception是从exception派生而来的,其声明位于头文件exce ption中;
如果新引发的异常与原来的异常规范不匹配,且原来的异常规范中包含了std ::bad_exception类型,则不匹配的异常将被std ::bad_exception异常所取代。
总之,如果要捕获所有的异常(不管是预期的异常还是意外异常),则可以这样做:
首先确保异常头文件的声明可用:
然后,设计一个替代函数,将意外异常转换为bad_exception异常,该函数的原型如下:
仅使用throw,而不指定异常将导致重新引发原来的异常。然而,如果异常规范中包含了这种类型,则该异常将被bad_exception对象所取代。
接下来在程序的开始位置,将意外异常操作指定为调用该函数:
最后,将bad_exception类型包括在异常规范中,并添加如下catch块序列: