异常:使用 MFC 宏和C++异常

本文讨论编写使用 MFC 异常处理宏和C++异常处理关键字的代码的注意事项。

本文涵盖以下主题:

混合异常关键字和宏

可以在同一程序中混合 MFC 异常宏和C++异常关键字。 但是,不能将 MFC 宏与同一块中的C++异常关键字混合,因为宏在超出范围时会自动删除异常对象,而使用异常处理关键字的代码则不会。 有关详细信息,请参阅 “异常:捕获和删除异常”一文。

宏和关键字之间的主要区别在于,当异常超出范围时,宏“自动”删除捕获的异常。 使用关键字的代码不;捕获块中捕获的异常必须显式删除。 混合宏和C++异常关键字可能会导致在未删除异常对象时内存泄漏,或者在删除异常两次时堆损坏。

例如,以下代码使异常指针失效:

TRY
{
   TRY
   {
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)  // The "inner" catch block
{
   throw;  // Invalid attempt to throw exception
         // to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e)  // The "outer" catch block
{
   // Pointer e is invalid because
   // it was deleted in the inner catch block.
}
END_CATCH

之所以出现问题,是因为 e 在执行从“内部” CATCH 块传出时被删除。 使用 THROW_LAST 宏而不是 THROW 语句将导致“outer” CATCH 块接收有效的指针:

TRY
{
   TRY
   {
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)  // The "inner" catch block
{
   THROW_LAST(); // Throw exception to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e)  // The "outer" catch block
{
   // Pointer e is valid because
   // THROW_LAST() was used.
}
END_CATCH

在 Catch 块内试用块

不能从 CATCH 块内的块中try重新引发当前异常。 以下示例无效:

TRY
{
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)
{
   try
   {
      throw;  // Wrong.  Causes e (the exception 
            // being thrown) to be deleted.
   }
   catch (CException* exception)
   {
      exception->ReportError();
   }
}
END_CATCH

有关详细信息,请参阅 异常:检查异常内容

另请参阅

异常处理