异常:从 MFC 异常宏转换
这是一个高级主题。
本文介绍如何将使用 Microsoft Foundation 类宏(TRY、CATCH、THROW 等)编写的现有代码转换为使用 C++ 异常处理关键字 try
、catch
和 throw
。 主题包括:
转换的优点
你可能不需要转换现有代码,但应注意 MFC 版本 3.0 中的宏实现与早期版本中的实现之间的差异。 这些差异和代码行为的后续更改在异常:3.0 版本中对异常宏的修改中进行了讨论。
转换的主要优点是:
使用 C++ 异常处理关键字的代码将编译为略小的 .EXE 或 .DLL。
C++ 异常处理关键字更加通用:它们可以处理可以复制的任何数据类型的异常(
int
、float
、char
等),而宏仅处理类CException
和从中派生的类的异常。
宏和关键字之间的主要区别在于,当异常超出范围时,使用宏的代码会“自动”删除捕获的异常。 使用关键字的代码不会,因此必须显式删除捕获的异常。 有关详细信息,请参阅文章异常:捕获和删除异常
另一个区别是语法。 宏和关键字的语法在三个方面有所不同:
宏参数和异常声明:
CATCH 宏调用具有以下语法:
CATCH(exception_class、exception_object_pointer_name)
请注意类名和对象指针名之间的逗号。
catch
关键字的异常声明使用以下语法:catch(exception_type、exception_name)
此异常声明语句指示 catch 块处理的异常的类型。
catch 块的分隔:
对于宏,CATCH 宏(带参数)开始第一个捕获块;AND_CATCH 宏开始后续的捕获块,END_CATCH 宏是捕获块序列的结尾。
使用关键字时,每个 catch 块以
catch
关键字(带异常声明)开始。 END_CATCH 宏没有对等项;捕获块以其闭合大括号结束。throw 表达式:
宏使用 THROW_LAST 重新引发当前异常。 没有参数的
throw
关键字具有相同的效果。
执行转换
使用宏转换代码以使用 C++ 异常处理关键字
查找所有出现的 MFC 宏 TRY、CATCH、AND_CATCH、END_CATCH、THROW 和 THROW_LAST。
替换或删除以下宏的所有匹配项:
TRY(将其替换为
try
)CATCH(将其替换为
catch
)AND_CATCH(将其替换为
catch
)END_CATCH(将其删除)
THROW(将其替换为
throw
)THROW_LAST(将其替换为
throw
)修改宏参数,使其形成有效的异常声明。
例如,更改
CATCH(CException, e)
用户身份登录到
catch (CException* e)
修改 catch 块中的代码,以便根据需要删除异常对象。 有关详细信息,请参阅文章异常:捕获和删除异常
下面是使用 MFC 异常宏的异常处理代码的示例。 请注意,由于以下示例中的代码使用这些宏,因此会自动删除异常 e
:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
if (m_bPassExceptionsUp)
THROW_LAST();
if (m_bReturnFromThisFunction)
return;
// Not necessary to delete the exception e.
}
END_CATCH
下一个示例中的代码使用 C++ exception 关键字,因此必须显式删除异常:
try
{
// Do something to throw an exception.
AfxThrowUserException();
}
catch (CException* e)
{
if (m_bPassExceptionsUp)
throw;
if (m_bThrowDifferentException)
{
e->Delete();
throw new CMyOtherException;
}
if (m_bReturnFromThisFunction)
{
e->Delete();
return;
}
e->Delete();
}
有关更多信息,请参见异常:使用 MFC 宏和 C++ 异常。