【发布时间】:2011-12-21 19:17:06
【问题描述】:
考虑以下代码sn-p:
struct ExceptionBase : virtual std::exception{};
struct SomeSpecificError : virtual ExceptionBase{};
struct SomeOtherError : virtual ExceptionBase{};
void MightThrow();
void HandleException();
void ReportError();
int main()
{
try
{
MightThrow();
}
catch( ... )
{
HandleException();
}
}
void MightThrow()
{
throw SomeSpecificError();
}
void HandleException()
{
try
{
throw;
}
catch( ExceptionBase const & )
{
// common error processing
}
try
{
throw;
}
catch( SomeSpecificError const & )
{
// specific error processing
}
catch( SomeOtherError const & )
{
// other error processing
}
ReportError();
}
void ReportError()
{
}
标准中的第 15.1.4 节告诉我们:
被抛出异常的临时副本的内存是 以未指定的方式分配,除非在 3.7.3.1 中注明。这 只要有一个正在执行的处理程序,临时就会持续存在 那个例外。特别是,如果处理程序通过执行 扔;语句,将控制权传递给另一个处理程序 例外,所以暂时保留。 当最后一个处理程序被 通过 throw 以外的任何方式为异常退出执行;这 临时对象被销毁,实现可能会释放 临时对象的内存;任何此类解除分配都在 一种未指定的方式。破坏发生后立即 在异常声明中声明的对象的销毁 处理程序。
我将main 中的处理程序视为“最后一个处理程序”是否正确?因此,HandleException 中允许任意数量的重新抛出和捕获,而不会导致当前异常对象的破坏?
【问题讨论】:
-
¤
main中的处理程序是最后一个,是的。是的,您可以根据需要多次重新抛出和重新捕获异常。但是,这不是一个好主意。相反,让您的处理程序执行 (1) 纯异常转换,或 (2) 纯日志记录和终止。该处理程序代码自然不具备处理故障的知识。欢呼吧, -
@Alf 谢谢。似乎我在发布一个小代码示例时省略了一些重要的细节。实际上,ExceptionBase 源自 boost::exception(从中提取了许多常见的上下文数据)。此外,
main实际上是任意数量的 COM 方法之一,因此在返回适当的 HRESULT 代码之前会记录错误(包括常见的和特定于错误的上下文数据)。但不管怎样,你已经回答了我的问题。
标签: c++ exception exception-handling