异常:从 MFC 异常宏转换

这是一个高级主题。

本文介绍如何将使用 Microsoft Foundation 类宏(TRY、CATCH、THROW 等)编写的现有代码转换为使用 C++ 异常处理关键字 trycatchthrow。 主题包括:

转换的优点

你可能不需要转换现有代码,但应注意 MFC 版本 3.0 中的宏实现与早期版本中的实现之间的差异。 这些差异和代码行为的后续更改在异常:3.0 版本中对异常宏的修改中进行了讨论。

转换的主要优点是:

  • 使用 C++ 异常处理关键字的代码将编译为略小的 .EXE 或 .DLL。

  • C++ 异常处理关键字更加通用:它们可以处理可以复制的任何数据类型的异常(intfloatchar 等),而宏仅处理类 CException 和从中派生的类的异常。

宏和关键字之间的主要区别在于,当异常超出范围时,使用宏的代码会“自动”删除捕获的异常。 使用关键字的代码不会,因此必须显式删除捕获的异常。 有关详细信息,请参阅文章异常:捕获和删除异常

另一个区别是语法。 宏和关键字的语法在三个方面有所不同:

  1. 宏参数和异常声明:

    CATCH 宏调用具有以下语法

    CATCH(exception_class、exception_object_pointer_name)

    请注意类名和对象指针名之间的逗号。

    catch 关键字的异常声明使用以下语法:

    catch(exception_type、exception_name)

    此异常声明语句指示 catch 块处理的异常的类型。

  2. catch 块的分隔:

    对于宏,CATCH 宏(带参数)开始第一个捕获块;AND_CATCH 宏开始后续的捕获块,END_CATCH 宏是捕获块序列的结尾

    使用关键字时,每个 catch 块以 catch 关键字(带异常声明)开始。 END_CATCH 宏没有对等项;捕获块以其闭合大括号结束

  3. throw 表达式:

    宏使用 THROW_LAST 重新引发当前异常。 没有参数的 throw 关键字具有相同的效果。

执行转换

使用宏转换代码以使用 C++ 异常处理关键字

  1. 查找所有出现的 MFC 宏 TRY、CATCH、AND_CATCH、END_CATCH、THROW 和 THROW_LAST

  2. 替换或删除以下宏的所有匹配项:

    TRY(将其替换为 try

    CATCH(将其替换为 catch

    AND_CATCH(将其替换为 catch

    END_CATCH(将其删除)

    THROW(将其替换为 throw

    THROW_LAST(将其替换为 throw

  3. 修改宏参数,使其形成有效的异常声明。

    例如,更改

    CATCH(CException, e)
    

    用户身份登录到

    catch (CException* e)
    
  4. 修改 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++ 异常

另请参阅

异常处理