差异:std :: runtime_error vs std :: exception()

std::runtime_errorstd::exception什么区别? 什么是适当的使用每个? 他们为什么不同呢?

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

std::runtime_error是一个更专门的类,从std::exception降序,意图在各种运行时错误的情况下被抛出。 它有一个双重目的。 它可以被自己抛出,或者它可以作为一个基类,以各种甚至更多的特定types的运行时错误exception,如std::range_errorstd::overflow_error等。您可以定义自己的exception类从std::runtime_error降序std::runtime_error ,以及你可以定义自己的exception类从std::exception降序。

就像std::runtime_error ,标准库包含std::logic_error ,也从std::exception降序。

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

PSdevise一个有用的exception类层次结构(这将使您只捕获您感兴趣的代码的每个点的exceptiontypes)是一项不重要的任务。 在标准C ++库中看到的是一种可能的方法,由语言的作者提供给你。 正如你所看到的,他们决定把所有的exceptiontypes分成“运行时错误”和“逻辑错误”,让你从那里继续处理你自己的exceptiontypes。 当然,还有其他方法来构build这个层次结构,这在您的devise中可能更合适。

更新:可移植性Linux与Windows

正如Loki Astari和unixman83在下面的回答和注释中指出的那样, exception类的构造函数不会根据C ++标准采取任何参数。 Microsoft C ++有一个构造函数在exception类中引入参数,但这不是标准的。 runtime_error类的构造函数在两个平台,Windows和Linux上都有参数( char* )。 为了便于携带,最好使用runtime_error

(请记住,仅仅因为你的项目规范说你的代码不必在Linux上运行,这并不意味着它不需要在Linux上运行。)

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

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

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