【问题标题】:What to throw when throwing C++ exceptions?抛出 C++ 异常时要抛出什么?
【发布时间】:2012-02-27 20:56:14
【问题描述】:

这可能是一个愚蠢的问题,但在 C++ 中,当我想抛出异常时......我应该抛出什么?

我应该抛出 std::exception,还是标准库保留的?或者我应该抛出一个字符串或整数?还是我应该扔任何我觉得合适的东西?

【问题讨论】:

  • 不要抛出字符串或整数!如果你总是抛出std::exception 的子类,你可以在main 中放置一个catch-all 子句来处理所有其他地方没有处理的异常并打印异常的what()

标签: c++ exception


【解决方案1】:

抛出一个派生自std::exception的类;如果您#include <stdexcept>,您可以从多个ready-made, useful 派生类中进行选择。

派生自std::exception 允许您的处理程序遵循可识别的样式,因为您始终可以使用.what() 来获取文本消息。不要抛出原始类型,因为它们不携带语义信息。

【讨论】:

  • 我会反驳(尽管实际上相同),在大多数情况下人们应该从 std::runtime_error 派生他们的异常(它本身恰好是从 std::exception 派生的)
【解决方案2】:

通常人们不会直接抛出 std::exception ,原因很简单,它不存储任何错误消息。什么方法返回不会有任何东西。有时我对此感到困惑,因为 MSVC 对此提供了非标准扩展,即 std::exception 中接受字符串的参数化构造函数。

您可以在 std::runtime_exception 等现有异常类中进行选择,也可以定义自己的异常类。这有点主观,但我建议将异常类的数量保持在最低限度,因为 RAII 可以消除对不同异常类型的多个代码分支和捕获块的大量需求。通常,消息与符合 RAII 的代码相结合,足以从任何异常中优雅地恢复。

最后,出于类似的原因,我建议您抛出的所有异常都继承自 std::exception。如果可以避免的话,您不希望为不同的异常类型乱扔许多不同的 catch 块。尽可能普遍地解决问题。

【讨论】:

    【解决方案3】:

    抛出源自std::exception 的东西的主要例外是,如果您使用的是具有自己的异常层次结构的框架(例如 MFC)。在这种情况下,您通常希望从其层次结构中的适当位置派生。

    请注意,我并不是特别试图将 MFC 作为干净异常处理(或一般的干净设计)的示例,而只是包含异常层次结构的框架示例。当您使用已定义异常层次结构的框架时,通常最好使用它。

    换句话说,与 C++ 中的偏好不同的是,人们普遍认为异常应该是一个单一的、单一的、具有单一根的层次结构。对于标准库,该单一根是 std::exception,但其他框架有替代方案,如果它们提供了一个,您通常希望将您的框架放入其中。

    【讨论】:

      【解决方案4】:

      与 java 不同,你可以抛出任何你想要的 (int, string, MyClass, ...)。但是听听Kerrek。 :)

      【讨论】:

        【解决方案5】:

        通常你会想要抛出从std::exception 派生的异常之一,正如其他人所说的那样。

        有时我会抛出其他类型,但前提是它被捕获在同一个块中并且该值在该上下文中有用。

        【讨论】:

        • 如果你正在“在同一个块内”捕获,你可能不应该首先抛出异常。例外是针对特殊情况的,但如果您可以在那里处理该情况,那么听起来它只是正常程序流程的一部分。 (并且不要忘记抛出异常可能比仅检查某个本地状态要昂贵得多。)
        • @KerrekSB,我不记得我这样做的确切情况,但我确信这是一个不属于正常流程的异常情况.可能也深深嵌套在替代方法会更丑陋的地方。
        • 很公平。 种情况下,异常可以使复杂的算法更清晰、更容易理解......
        猜你喜欢
        • 2013-05-24
        • 1970-01-01
        • 2011-04-11
        • 1970-01-01
        • 2010-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多