异常:使用 MFC 宏和 C++ 异常
本文讨论编写同时使用 MFC 异常处理宏和 C++ 异常处理关键字书写代码的注意事项。
本文涵盖以下主题:
混合异常关键字和宏
可以在同一程序中混合 MFC 异常宏和 C++ 异常关键字。 但是,不能将 MFC 宏与同一块中的 C++ 异常关键字混合在一起,因为宏在超出范围时会自动删除异常对象,而使用异常处理关键字的代码则不会。 有关详细信息,请参阅文章异常:捕获和删除异常
宏和关键字之间的主要区别在于,当异常超出范围时,该宏会“自动”删除捕获的异常。 使用关键字的代码不会;catch 块中捕获的异常必须显式删除。 混合宏和 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
之所以出现问题,是因为执行从“内部”CATCH 块传出时删除 e
。 使用 THROW_LAST 宏而不是 THROW 语句将导致“外部”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
有关详细信息,请参阅 异常:检查异常内容。