C++ 重新抛出异常

2024年8月28日 | 阅读 4 分钟

捕获到的异常可以在try 块中捕获,并使用一个或多个 Catch 块处理。在某些情况下,异常需要使用单个Catch 块捕获并重新抛出,因为调用栈顶部的Catch 块可以处理相应的异常。这个过程可以概括为重新抛出异常

重新抛出异常时保留其类型和详细信息,使其能够进一步向上层调用栈传播。当需要在多个程序级别处理不同的异常,或者在异常解决之前需要执行其他活动时,这会很有用。

示例代码

输出

Caught exception in innerFunction: Exception occurred!
Caught exception in outerFunction: Exception occurred!

说明

在这个例子中,innerFunction() 抛出了一个 std::runtime_error。在 innerFunction() 的 catch 块内,使用 throw; 重新抛出异常。这表明 outerFunction() 的 catch 块将再次捕获该异常。main() 函数在最高级别进行处理,异常最终可以在这里被捕获。

重新抛出异常允许您选择程序如何处理它们,并确保它们在适当的级别被捕获和处理。

  • 重新抛出异常时会保留其类型。当使用 throw; 命令重新抛出异常时,它基本上是沿着调用栈向上传递,以便被另一个 catch 块捕获和处理。异常的原始类型得以保留,使得上层 catch 块能够有效地处理特定类型的异常。
  • 重新抛出允许额外处理: 您可以在重新抛出异常之前执行更多操作或记录有关异常的额外信息,或者更改其状态。例如,您可以添加调试信息、添加额外上下文,或者将原始异常封装在另一个异常中,以便为上层 catch 块提供更有用的信息。
  • 通过引用捕获异常: 再次抛出异常时,通过引用而不是通过值捕获它至关重要(例如,const std::exception&)。当通过引用捕获异常时,可以确保即使在异常处理过程中被多次捕获和重新抛出之后,异常对象仍然有效。
  • 在调用栈的任何阶段重新抛出但未被捕获的异常被称为未捕获异常。未被捕获的异常可以由 std::terminate function() 处理,它会在不进行任何栈展开或清理步骤的情况下终止代码。
  • 异常传播: 再次抛出异常会导致它们在调用栈中向上层传播,直到最终在 catch 块中停止,在那里它们可以被正确处理。调用栈中的任何函数都可以通过捕获并重新抛出异常来阻止异常的传播。使用这种策略,可以以适合其发生情况的方式处理异常。
  • 使用新异常重新抛出: 重新抛出异常时,您可以选择抛出一个新异常来代替旧异常。要实现此目的,请创建一个新的异常对象并在 catch 块内抛出它。使用此方法,您可以在初始异常被调用栈上层再次捕获之前添加信息。
  • 重新抛出嵌套异常: 异常有时可能是嵌套的,其中一个异常在另一个异常的 catch 块中被引发。重新抛出的嵌套异常将作为外部异常的 std::nested_exception 包含在内。如果需要,它允许您分别捕获和管理外部异常和嵌套异常。