差异: std: : run_error 与 std: : eption()

std::runtime_errorstd::exception有什么不同?每种药物的适当用途是什么?为什么他们一开始就不一样?

100971 次浏览

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 VS Windows

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

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

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";
}