异常:对于异常宏的更改在3.0版中
这是一个高级主题。
在 MFC 3.0 版和更高版本中,异常处理的宏已更改为使用 C++ 异常。本文调用这些更改会影响使用宏现有代码的行为。
本文包含以下主题:
异常类型和 catch 宏
再次引发的异常。
异常类型和 catch 宏
在 MFC 的早期版本中, CATCH 宏使用 MFC 运行时类型信息确定异常类型;异常类型确定的,也就是说,在 catch 站点。具有 C++ 异常,但是,异常类型总是定位在引发网站由引发的异常对象的类型。将指针的类型设置为引发的对象的与引发的对象的类型不同的极少数情况下会导致不兼容。
下面的示例阐释了此差异的结果在 MFC 3.0 版及更早版本之间的:
TRY
{
THROW( (CException*) new CCustomException() );
}
CATCH( CCustomException, e )
{
TRACE( "MFC 2.x will land here\n" );
}
AND_CATCH( CException, e )
{
TRACE( "MFC 3.0 will land here\n" );
}
END_CATCH
,因为控件总是传递给第一 catch 块相匹配的异常声明,此代码的行为有所不同使用 3.0 版。引发表达式的结果
THROW( (CException*) new CCustomException() );
被作为 CException*,因此,即使该构造为 CCustomException。在 MFC 2.5 版和更早的使用 CObject::IsKindOf 的 CATCH 宏测试类型在运行时。由于表达式
e->IsKindOf(RUNTIME_CLASS(CException));
为 true,第一个 catch 块捕获异常。在版本 3.0 中,使用 C++ 异常实现许多异常处理的宏,第二个 catch 块匹配时引发的 CException。
象这样的代码很少见。通常出现异常对象传递给接受泛型 **CException***的另一个函数,执行 “进程的之前引发”最后引发异常。
,在生成异常时,若要解决此问题,从函数将引发表达式移动到调用代码并引发实际类型的异常的编译器知道。
再次引发的异常。
catch 块中不能引发它捕获的相同异常指针。
例如,此代码是有效的旧版本,但是,与 3.0 版的意外结果:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH( CException, e )
{
THROW( e ); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
使用 catch 块中的 THROW 块原因指针要删除的 e ,因此,外部 catch 站点将接收到无效的指针。使用 THROW_LAST 再次引发 e。
有关更多信息,请参见 异常:捕获和删除异常。