问题描述
我有两个从std :: runtime_error继承的异常类。第一个AError
可以正常工作。
class AError : public std::runtime_error {
public:
const char* what() const noexcept
{
return "Error of type A!";
}
};
第二个BError
无法编译,因为std::runtime_error
没有默认的构造函数。
class BError : public std::runtime_error {
public:
const int num_;
BError(int n) : num_(n) {}; // ERROR: no default constructor for runtime_error
const char* what() const noexcept
{
return "Error of type B!";
}
};
在我看来AError
不应编译,因为AError
的默认构造函数应调用默认构造函数std::runtime_error
中的AError
的默认构造函数。允许该示例进行编译的默认AError
构造器中发生了什么?
解决方法
在我看来,AError不应该编译,因为AError的默认构造函数应在默认构造函数AError中调用std :: runtime_error的默认构造函数。
AError
的默认ctor被删除,因为它继承自没有默认ctor的类。尝试以下操作,代码将无法编译
AError er;
,
编译AError
的定义是因为它没有默认的构造函数(一个不接受任何参数的构造函数)。由于std::runtime_error
没有一个默认构造函数,因此可以隐式生成默认构造函数。该类定义本身没有可诊断的错误,因为它不会创建该类的任何实例。
使用默认构造函数创建AError
实例的尝试均存在可诊断的错误
AError an_error; // error since AError cannot be default constructed
在BError
中,构造函数的定义(在类BError
中)
BError(int n) : num_(n) {}; // ERROR: no default constructor for runtime_error
试图隐式构造基数std::runtime_error
,即使它未在初始化程序列表中列出。因此,此定义在功能上等同于
BError(int n) : std::runtime_error(),num_(n) {};
并且是可诊断的错误,这是由于尝试使用std::runtime_error
的(不存在的)默认构造函数(对于编译器而言是显而易见的)。
只需使用std::runtime_error
中的适当构造函数即可完成此编译,例如
BError(int n) : std::runtime_error(""),num_(n) {};
它将调用接受std::runtime_error
的{{1}}的构造函数。