用 C++ 编写自定义异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13258786/
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 17:07:53  来源:igfitidea点击:

Writing custom exceptions in C++

c++custom-exceptions

提问by lorefnon

I am coming from a Ruby and Java background and have recently begun exploring C++.

我来自 Ruby 和 Java 背景,最近开始探索 C++。

While my initial attempts at creating custom exceptions by simply subclassing exception class failed with obscure, I found the following example posted on a site:

虽然我最初尝试通过简单地对异常类进行子类化来创建自定义异常失败了,但我发现以下示例发布在网站上:

class Exception : public exception
{
public:
  Exception(string m="exception!") : msg(m) {}
  ~Exception() throw() {}
  const char* what() const throw() { return msg.c_str(); }

private:
  string msg;
};

My understanding of semantics of C++ is not very mature at the moment, and I would like to have a better understanding of what is going on here.

目前我对C++语义的理解还不是很成熟,希望对这里发生的事情有更深入的了解。

In the statement const char* what() const throw()what does the part const throw()do, and what kind of programming construct is it?

在语句const char* what() const throw()中该部分是const throw()做什么的,它是一种什么样的编程结构?

Also, what is the purpose and intent of throw()in the destructor specification ~Exception()and why do I need to have a destructor specification although I don't need it do something in particular? Shouldn't the destructorinherited from exception be sufficient?

另外,throw()析构函数规范的目的和意图是什么~Exception(),为什么我需要一个析构函数规范,尽管我不需要它做一些特别的事情?不应该destructor从异常继承就足够了吗?

回答by jamesdlin

constafter a method declares that the method does not mutate the object. (There are exceptions, and generally it's used to mean "does not mutate the object in an externally-visible way.)

const在方法声明该方法不会改变对象之后。(也有例外,通常它用于表示“不会以外部可见的方式改变对象。)

The throw()after the method declaration is an exception specification; it's similar to the throws E1, E2exception specifications that you see in Java. However, in C++, exception specifications are not checked at compilation-time and are generally considered to be mostly useless (they are now deprecated). throw()is the only somewhat useful form, meaning that the function declares that it must not throw an exception (and if it does, it's a logical error, and the program will invoke an unexpected exception handler, by default terminating the program).

throw()方法声明之后是异常规范; 它类似于throws E1, E2您在 Java 中看到的异常规范。但是,在 C++ 中,异常规范不会在编译时检查,通常被认为是无用的(它们现在已弃用)。throw()是唯一有点有用的形式,这意味着该函数声明它不能抛出异常(如果抛出异常,则这是一个逻辑错误,并且程序将调用意外的异常处理程序,默认情况下终止程序)。

The destructor is explicitly declared because if left unspecified, the compiler will generate a destructor that invokes the base class destructor, and the compiler-generated destructor will not use a throw()exception specification (despite the fact that throwing exceptions in destructors is never a good idea).

显式声明析构函数是因为如果未指定,编译器将生成调用基类析构函数的析构函数,编译器生成的析构函数将不使用throw()异常规范(尽管在析构函数中抛出异常从来不是一个好主意) .

回答by Peter Wildemann

You are currently dealing with some style things of C++! So when you want to actually have an exception-object you may use std::exception, which is explained here on cppreference.

您目前正在处理一些 C++ 风格的东西!因此,当您想要实际拥有一个exception-object 时,您可以使用std::exception在 cppreference 上对此进行了解释。

But since you could throw and catch everything in C++, you may even define your own exception class or use more basic aspects, e.g.

但是由于您可以在 C++ 中抛出和捕获所有内容,您甚至可以定义自己的异常类或使用更基本的方面,例如

try  {
    throw("S0M3, M4YB3 CR1PT1C STR1NG!");  
} catch(char const* exceptStr) {  
    SomeFuncThatDecodesTheString(exceptStr); 
}

Your other topics are more a kind of personal style or standard:

你的其他话题更像是一种个人风格或标准:

  • An empty destructor like ~FooClass() {}is only there two show "I really do nothing!". Sometimes they might also be useful, when you use a strict system for writing your classes (e.g. First the public space, including the standard ctor at first and the standard dtor as the second function ...) to kind of force you (or some other coder) to write into the existing braces/function and therefore not desroying your holy order :)
  • You may write a throw()behind classes for insurance to other people, that the class does only throw exceptions of the types stated in the parantheses. Therefore a function void FooFunc() throw(int,char)shouldonly throw intsand chars. And an empty throw()is just to actually say "Hey coder, I do not throw anything!". You will often find this in the C++ standard library, since you are (mostly) only able to look at the prototypes and not the source. BTW the throw(someType(s))might be a lie. The function maythrow any other type or simply nothing! But don't be a liar, when you use this ;)
  • 一个空的析构函数就像~FooClass() {}只有两个显示“我真的什么都不做!”。有时它们也可能有用,当您使用严格的系统编写类时(例如,首先是公共空间,首先包括标准 ctor 和作为第二个功能的标准 dtor ...)迫使您(或某些其他编码器)写入现有的大括号/函数,因此不会破坏您的神圣秩序:)
  • 您可以throw()为其他人编写一个隐藏类,该类只抛出括号中所述类型的异常。因此一个函数void FooFunc() throw(int,char)应该只抛出intschars。而空throw()只是实际上说“嘿编码器,我不扔任何东西!”。您经常会在 C++ 标准库中找到它,因为您(大部分)只能查看原型而不是源代码。顺便说一句,这throw(someType(s))可能是谎言。该函数可能抛出任何其他类型或根本什么都不抛出!但是,当您使用它时,请不要撒谎;)

EDIT:

编辑:

I wanted to add, that noexceptcan (since C++11) also be used to declare an function, not to throw any exception. This is pretty more comprehensible than throw().

我想补充一点,这noexcept也可以(自C++11 起)用于声明函数,而不是抛出任何异常。这比 更容易理解throw()

LG ntor

LG ntor

回答by jimvonmoon

throw()in the destructor specification means that the destructor doesn't throw exceptions. Destructors in C++ should not throw exceptions - here is why.

throw()在析构函数规范中意味着析构函数不会抛出异常。C++ 中的析构函数不应抛出异常 -这就是为什么.

Destructors in C++ are not inherited. If you don't write your own destructor then compiler will automatically generate a destructor for you. That destructor will call destructor of a base class if such class exists.

C++ 中的析构函数不是继承的。如果您不编写自己的析构函数,那么编译器会自动为您生成一个析构函数。如果基类存在,该析构函数将调用基类的析构函数。

constspecifier in Exception::what()declaration means that this method may be called for constant objects of type Exception. throw()specifier means the same as for the destructor.

constException::what()声明中的说明符意味着可以为类型为 的常量对象调用此方法Exceptionthrow()说明符的含义与析构函数相同。

You should get a book about C++, those are very basic questions.

你应该得到一本关于 C++ 的书,这些都是非常基本的问题。