std :: runtime_error

问题描述

我有两个从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}}的构造函数。