C++ 区别: std::runtime_error 与 std::exception()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1569726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:27:46  来源:igfitidea点击:

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

c++exception-handling

提问by sivabudh

What is the difference between std::runtime_errorand std::exception? What is the appropriate use for each? Why are they different in the first place?

std::runtime_error和 和有std::exception什么区别?每个人的适当用途是什么?为什么它们首先不同?

回答by AnT

std::exceptionis the class whose only purpose is to serve as the base class in the exception hierarchy. It has no other uses. In other words, conceptually it is an abstractclass (even though it is not defined as abstract class in C++ meaning of the term).

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

std::runtime_erroris a more specialized class, descending from std::exception, intended to be thrown in case of various runtimeerrors. It has a dual purpose. It can be thrown by itself, or it can serve as a base class to various even more specialized types of runtime error exceptions, such as std::range_error, std::overflow_erroretc. You can define your own exception classes descending from std::runtime_error, as well as you can define your own exception classes descending from std::exception.

std::runtime_error是一个更专业的类,来自std::exception,旨在在各种运行时错误的情况下抛出。它有双重目的。它可以通过自身被抛出,或者它可以作为一个基类各种更专门类型的运行时错误异常,如std::range_errorstd::overflow_error等你可以定义自己的异常类从降std::runtime_error,以及你可以定义自己的异常从std::exception.

Just like std::runtime_error, standard library contains std::logic_error, also descending from std::exception.

就像std::runtime_error,标准库包含std::logic_error,也从std::exception.

The point of having this hierarchy is to give user the opportunity to use the full power of C++ exception handling mechanism. Since 'catch' clause can catch polymorphic exceptions, the user can write 'catch' clauses that can catch exception types from a specific subtree of the exception hierarchy. For example, catch (std::runtime_error& e)will catch all exceptions from std::runtime_errorsubtree, letting all others to pass through (and fly further up the call stack).

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

P.S. Designing a useful exception class hierarchy (that would let you catch only the exception types you are interested in at each point of your code) is a non-trivial task. What you see in standard C++ library is one possible approach, offered to you by the authors of the language. As you see, they decided to split all exception types into "runtime errors" and "logic errors" and let you proceed from there with your own exception types. There are, of course, alternative ways to structure that hierarchy, which might be more appropriate in your design.

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

Update: Portability Linux vs Windows

更新:可移植性 Linux 与 Windows

As Loki Astari and unixman83 noted in their answer and comments below, the constructor of the exceptionclass does not take any arguments according to C++ standard. Microsoft C++ has a constructor taking arguments in the exceptionclass, but this is not standard. The runtime_errorclass has a constructor taking arguments (char*) on both platforms, Windows and Linux. To be portable, better use runtime_error.

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

(And remember, just because a specification of your project says your code does not have to run on Linux, it does not mean it does never have to run on Linux.)

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

回答by Martin York

std::exceptionshould be considered (note the considered) the abstract base of the standard exception hierarchy. This is because there is no mechanism to pass in a specific message (to do this you must derive and specialize what()). There is nothing to stop you from using std::exception and for simple applications it may be all you need.

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

std::runtime_erroron the other hand has valid constructors that accept a string as a message. When what()is called a const char pointer is returned that points at a C string that has the same string as was passed into the constructor.

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