C++ 我应该从 std::exception 继承吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1669514/
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
Should I inherit from std::exception?
提问by John M Gant
I've seen at least one reliable source (a C++ class I took) recommend that application-specific exception classes in C++ should inherit from std::exception
. I'm not clear on the benefits of this approach.
我已经看到至少一个可靠的来源(我使用的一个 C++ 类)建议 C++ 中特定于应用程序的异常类应该从std::exception
. 我不清楚这种方法的好处。
In C# the reasons for inheriting from ApplicationException
are clear: you get a handful of useful methods, properties and constructors and just have to add or override what you need. With std::exception
it seems that all you get is a what()
method to override, which you could just as well create yourself.
在 C# 中,继承 from 的原因ApplicationException
很明确:您可以获得一些有用的方法、属性和构造函数,只需添加或覆盖您需要的内容。有了std::exception
这一切似乎你得到的是一个what()
覆盖方法,你也可以同样创造自己。
So what are the benefits, if any, of using std::exception
as a base class for my application-specific exception class? Are there any good reasons not to inherit from std::exception
?
那么,将其std::exception
用作特定于应用程序的异常类的基类有什么好处(如果有的话)?有什么好的理由不继承std::exception
吗?
采纳答案by Nikolai Fetissov
The main benefit is that code using your classes doesn't have to know exact type of what you throw
at it, but can just catch
the std::exception
.
Edit:as Martin and others noted, you actually want to derive from one of the sub-classes of std::exception
declared in <stdexcept>
header.
主要的好处是使用类不必知道你确切类型的代码throw
吧,但正好可以catch
的std::exception
。
编辑:正如 Martin 和其他人所指出的,您实际上想要从header中std::exception
声明的子类之一派生<stdexcept>
。
回答by Martin York
The problem with std::exception
is that there is no constructor (in the standard compliant versions) that accepts a message.
问题std::exception
在于没有接受消息的构造函数(在标准兼容版本中)。
As a result I prefer to derive from std::runtime_error
. This is derived from std::exception
but its constructors allow you to pass a C-String or a std::string
to the constructor that will be returned (as a char const*
) when what()
is called.
因此,我更喜欢从std::runtime_error
. 这是派生自std::exception
但它的构造函数允许您将 C-String 或 a 传递给std::string
将在调用char const*
时返回(作为 a )的构造函数what()
。
回答by Aleksei Potov
Reason for inheriting from std::exception
is it "standard" base class for exceptions, so it is natural for other people on a team, for example, to expect that and catch base std::exception
.
继承 from 的原因std::exception
是它是异常的“标准”基类,因此团队中的其他人很自然地期望并捕获 base std::exception
。
If you are looking for convenience, you can inherit from std::runtime_error
that provides std::string
constructor.
如果您正在寻找方便,您可以从std::runtime_error
提供std::string
构造函数继承。
回答by timday
I once participated in the clean up of a large codebase where the previous authors had thrown ints, HRESULTS, std::string, char*, random classes... different stuff everywhere; just name a type and it was probably thrown somewhere. And no common base class at all. Believe me, things were much tidier once we got to the point that all the thrown types had a common base we could catch and know nothing was going to get past. So please do yourself (and those who'll have to maintain your code in future) a favor and do it that way from the start.
我曾经参与过一个大型代码库的清理工作,以前的作者在其中抛出了整数、HRESULTS、std::string、char*、随机类……到处都是不同的东西;只需命名一个类型,它可能会被扔到某个地方。并且根本没有共同的基类。相信我,一旦我们发现所有抛出的类型都有一个共同的基础,我们可以捕获并且知道什么都不会过去,事情就会变得更整洁。所以请帮自己(以及那些将来必须维护您的代码的人)一个忙,并从一开始就这样做。
回答by James Schek
You should inherit from boost::exception. It provides a lot more features and well-understood ways to carry additional data... of course, if you're not using Boost, then ignore this suggestion.
您应该从boost::exception继承。它提供了更多的功能和易于理解的方式来携带额外的数据......当然,如果你不使用Boost,那么忽略这个建议。
回答by Emil
Yes you should derive from std::exception
.
是的,您应该从std::exception
.
Others have answered that std::exception
has the problem that you can't pass a text message to it, however it is generally not a good idea to attempt to format a user message at the point of the throw. Instead, use the exception object to transport all relevant information to the catch site which can then format a user-friendly message.
其他人已经回答说std::exception
存在您无法向其传递文本消息的问题,但是在抛出时尝试格式化用户消息通常不是一个好主意。相反,使用异常对象将所有相关信息传输到捕获站点,然后可以格式化用户友好的消息。
回答by SingleNegationElimination
The reason why you might want to inherit from std::exception
is because it allows you to throw an exception that is caught according to that class, ie:
您可能想要继承自std::exception
的原因是因为它允许您抛出根据该类捕获的异常,即:
class myException : public std::exception { ... };
try {
...
throw myException();
}
catch (std::exception &theException) {
...
}
回答by Kirill V. Lyadvinsky
There is one problem with inheritance that you should know about is object slicing. When you write throw e;
a throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw
. That could be not what you're expecting. Example of problem you could find here.
您应该了解的一个继承问题是对象切片。当您编写throw e;
throw 表达式时,会初始化一个临时对象,称为异常对象,其类型是通过从 的操作数的静态类型中删除任何顶级 cv 限定符来确定的throw
。那可能不是您所期望的。您可以在此处找到问题示例。
It is not an argument against inheritance, it is just 'must know' info.
这不是反对继承的论据,它只是“必须知道”的信息。
回答by AnT
Difference: std::runtime_error vs std::exception()
区别: std::runtime_error 与 std::exception()
Whether you shouldinherit from it or not is up to you. Standard std::exception
and its standard descendants propose one possible exception hierarchy structure (division into logic_error
subhierarchy and runtime_error
subhierarchy) and one possible exception object interface. If you like it - use it. If for some reason you need something different - define your own exception framework.
你是否应该继承它取决于你。Standardstd::exception
及其标准后代提出了一种可能的异常层次结构(分为logic_error
subhierarchy 和runtime_error
subhierarchy)和一种可能的异常对象接口。如果你喜欢它 - 使用它。如果由于某种原因您需要不同的东西 - 定义您自己的异常框架。
回答by Mark Ransom
If all your possible exceptions derive from std::exception
, your catch block can simply catch(std::exception & e)
and be assured of capturing everything.
如果所有可能的异常都源自std::exception
,则您的 catch 块可以简单catch(std::exception & e)
地确保捕获所有内容。
Once you've captured the exception, you can use that what
method to get more information. C++ doesn't support duck-typing, so another class with a what
method would require a different catch and different code to use it.
捕获异常后,您可以使用该what
方法获取更多信息。C++ 不支持鸭子类型,因此具有what
方法的另一个类将需要不同的捕获和不同的代码才能使用它。