区别:std :: runtime_error vs std :: exception()

时间:2009-10-15 00:35:49

标签: c++ exception-handling

std::runtime_errorstd::exception之间有什么区别?每种用途的适当用途是什么?为什么它们首先是不同的?

2 个答案:

答案 0 :(得分:143)

std::exception是一个类,其唯一目的是作为异常层次结构中的基类。它没有其他用途。换句话说,从概念上讲它是一个抽象类(即使它没有被定义为该术语的C ++含义中的抽象类)。

std::runtime_error是一个更专业的类,从std::exception开始,旨在抛出各种运行时错误。它有双重目的。它可以单独抛出,也可以作为各种更特殊类型的运行时错误异常的基类,例如std::range_errorstd::overflow_error等。您可以定义自己的异常类来自std::runtime_error,以及您可以从std::exception开始定义自己的异常类。

std::runtime_error一样,标准库包含std::logic_error,也来自std::exception

拥有这种层次结构的目的是让用户有机会使用C ++异常处理机制的全部功能。由于'catch'子句可以捕获多态异常,因此用户可以编写'catch'子句,可以从异常层次结构的特定子树中捕获异常类型。例如,catch (std::runtime_error& e)将捕获std::runtime_error子树中的所有异常,让所有其他异常通过(并进一步向上移动调用堆栈)。

P.S。设计一个有用的异常类层次结构(只允许在代码的每个点捕获您感兴趣的异常类型)是一项非常重要的任务。您在标准C ++库中看到的是一种可能的方法,由该语言的作者提供给您。如您所见,他们决定将所有异常类型拆分为“运行时错误”和“逻辑错误”,然后让您从那里继续使用自己的异常类型。当然,还有其他方法来构建层次结构,这可能更适合您的设计。

更新:Linux可移植性与Windows

正如Loki Astari和unixman83在下面的回答和评论中指出的那样,exception类的构造函数根据C ++标准不接受任何参数。 Microsoft C ++有一个构造函数在exception类中接受参数,但这不是标准的。 runtime_error类在两个平台,Windows和Linux上都有一个带参数(char*)的构造函数。为了便携,请更好地使用runtime_error

(请记住,只是因为您的项目规范说您的代码不必在Linux上运行,这并不意味着它永远不必在Linux上运行。)

答案 1 :(得分:17)

应该考虑std :: exception(注意考虑)标准异常层次结构的抽象基础。这是因为没有传递特定消息的机制(要做到这一点,你必须派生并专门化what())。没有什么可以阻止你使用std :: exception,对于简单的应用程序,它可能就是你所需要的。

另一方面,

std :: runtime_error具有接受字符串作为消息的有效构造函数。当调用what()时,返回一个const char指针,该指针指向一个C字符串,该字符串与传递给构造函数的字符串相同。

try
{
    if (badThingHappened)
    {
         throw std::runtime_error("Something Bad happened here");
    }
}
catch(std::exception const& e)
{
    std::cout << "Exception: " << e.what() << "\n";
}