创建异常时构造函数语法的差异(c ++)

时间:2015-01-25 22:21:12

标签: c++ class c++11 constructor runtime-error

所以背景,我在Java编程语言方面有很强的背景。在C ++语言方面,我是一个完全的菜鸟。基本上我知道在C ++中有两种不同的语法来定义构造函数,我只是不明白它们的区别。

在编写异常构造函数时,如下所示(在类似于没有返回类型的方法的庄园中),编译器输出no matching function for call to 'std::runtime_error::runtime_error()'错误:

#include <stdexcept>
using namespace std;

class DivideByZeroException : public runtime_error {
public :
    DivideByZeroException() {
        runtime_error("attempted to divide by zero.");
    }
};

但是,当构造函数被修改为以下内容时,代码编译无错误:

#include <stdexcept>
using namespace std;

class DivideByZeroException : public runtime_error {
public :
    DivideByZeroException() :
        runtime_error("attempted to divide by zero."){};
};

有人可以解释一下这里发生了什么吗?

2 个答案:

答案 0 :(得分:3)

在第二个例子中,冒号和左括号之间的部分称为initialization list。它是初始化成员和基类的地方。如果您不使用初始化列表(如第一个示例中所示),则默认初始化您的成员和基类。但std::runtime_error没有默认构造函数,这就是导致错误的原因。

no matching function for call to 'std::runtime_error::runtime_error()'

编译器正在尝试调用std::runtime_error的默认构造函数,但它不存在。因此必须在初始化列表中初始化。至于第一个例子的构造函数中的代码行:

DivideByZeroException() {
    runtime_error("attempted to divide by zero.");   // this one
}

构造一个临时runtime_error对象,该对象与DivideByZeroException对象的基本成员完全无关。这个临时表在表达式结束时被销毁。

  

基本上我知道有两种不同的语法用于定义   C ++中的构造函数

通过这个,我假设你的两种方式是(1)with和(2)没有初始化列表。通常这是真的。但是,在某些情况下,与您的一样,只有一种方法。也就是说,带有初始化列表。

答案 1 :(得分:2)

异常没有什么特别之处。 (事实上​​,与Java不同,C ++在异常类和任何其他类之间没有任何区别,如果你愿意,你可以抛出整数。)

构造函数只有一种正确的语法,而它是第二种。第一个片段做了一些不同的事情:首先,它试图在没有参数的情况下调用基础构造函数(即它与编写DivideByZeroException() : runtime_error() { runtime_error("message"); }的情况相同),然后创建一个临时的runtime_error构造函数体中的对象并立即丢弃它(正文中的runtime_error行与在Java中单独编写new RuntimeException()的效果大致相同。

发生错误是因为runtime_error没有没有参数的构造函数,因此调用这样的构造函数的隐式尝试失败。