首页 > 解决方案 > try/catch 和 MFC TRY/CATCH 有什么区别?

问题描述

我正在重构一些遗留的 C++ MFC 代码并且遇到了这个结构:

TRY
{
    // do some stuff
}
CATCH
{
    // do some other stuff
}
END_CATCH

TRY/CATCH对我来说,这似乎很不寻常,我试图了解使用try/catch.

我看到它TRY创建了一个实例,AFX_EXCEPTION_LINK但我不太明白它的目的。我的谷歌搜索技能惨遭失败。

标签: visual-c++mfc

解决方案


MFC(及其异常处理宏)早于 C++98 语言规范。在 MFC 中使用异常时,宏会尝试抽象出常见的样板代码。由于设计决定,样板代码是必要的,MFC 中的异常是动态分配的1,需要手动处理。

将 MFC 异常处理宏替换为 C++ 异常处理所需的步骤记录在Exceptions: Converting from MFC Exception Macros下:

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

  1. 找到所有出现的 MFC 宏TRYCATCHAND_CATCHEND_CATCHTHROWTHROW_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++ 异常关键字,因此必须显式删除异常:

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();
}

转换几乎是机械的,只要您记得通过调用CException::Delete手动删除 MFC 异常。


1 这与当今的 C++ 异常处理约定相反:按值抛出,按 (const) 引用捕获。


推荐阅读