【问题标题】:Proper use of exceptions in C++在 C++ 中正确使用异常
【发布时间】:2012-05-07 09:02:13
【问题描述】:

在 C++ 中,我应该使用 std::runtime_error 来指示发生了某种错误,还是应该创建继承自 std::runtime_error 的自定义异常,以便更好地处理它们。

例如,如果我以某种方式从用户那里得到输入,那会更好:

if (inputInvalid)
{
    throw std::runtime_error("Invalid input!");
}

对比...

class invalid_input
    : public std::runtime_error /* or should I inherit from std::exception? */
{
public:
    invalid_input()
        : std::runtime_error("Invalid input!")
    {
    };
};

-------------------------------------------------------

if (inputInvalid)
{
    throw invalid_input();
}

哪个被认为更好地使用异常处理/哪个更好?

【问题讨论】:

  • 后者可以捕获这种特定类型的运行时错误,而第一个只允许您捕获“a”运行时错误。哪个更好实际上取决于您计划如何处理错误。
  • 这是一个非常敏感的话题,每个人都有不同的看法。看看Go-like 方法(throw 终止任务,因此不需要有不同的类型)与Java 方法及其非常复杂的层次结构。

标签: c++ exception coding-style exception-handling runtime-error


【解决方案1】:

在您给出的示例中,我将为您的 invalid_input 类继承 std::exception() 。通常,用户输入错误不被视为运行时错误,您可能希望更早地捕获它,您可能希望在它发生时执行不同的逻辑。在这种情况下,在大多数情况下从 runtime_exception 使用或子类化会导致“is a”测试失败。

【讨论】:

    【解决方案2】:

    这将取决于项目的规模。如果您在做一些小事情并且只需要快速而肮脏的东西,那么 std:runtime_error 就可以了。但是如果你在一个大项目上工作,你会想要创建自己的自定义异常来帮助管理(通过捕获)所有不同的可能性。否则现在如果你抓到了,你就会抓到所有的东西,如果你需要用不同的方法来捕获多个不同的东西,这可能是个问题。

    我也会读这个:

    Difference: std::runtime_error vs std::exception()

    【讨论】:

      【解决方案3】:

      我只会在以下两种情况之一中子类化标准异常类:

      1. 所有标准异常类都没有描述异常性质的名称
      2. 我的异常需要额外的信息,而不是标准异常中的信息(即描述错误的字符串)。

      否则,没有什么意义。特别是如果其他人必须与您的代码交互并想知道为什么有一个自定义异常类不执行标准异常不执行的任何操作。

      【讨论】:

        【解决方案4】:

        始终考虑从继承 std::runtime_error 中获得什么。它是否让您更容易处理错误?在示例代码中,它没有带来任何好处,所以如果它所做的一切都是一样的,那么从 std::runtime_error 继承是没有意义的。如果您想添加比 std::runtime_error 更多的信息,那么您可能需要继承这些信息并将其添加到您的错误类中。

        【讨论】:

          猜你喜欢
          • 2014-08-08
          • 2020-08-13
          • 2013-12-12
          • 1970-01-01
          • 2021-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多