为什么编译器会为我的异常类寻找默认构造函数?

时间:2015-06-19 13:55:00

标签: c++ default-constructor

我为我的库定义了一个小的异常层次结构。它继承自 std :: runtime_error ,如下所示:

class library_exception : public std::runtime_error {
    using std::runtime_error::runtime_error;
};

class specific_exception : public library_exception {
    int guilty_object_id;

    specific_exception(int guilty_object_id_)
        : guilty_object_id(guilty_object_id_) {}
};

编译器说:

  

错误:调用隐式删除的默认构造函数' library_exception'

并指向 specific_exception 构造函数。

为什么要在这里调用默认构造函数?

2 个答案:

答案 0 :(得分:4)

library_exception继承自std::runtime_error。后者没有默认构造函数,这意味着前者不是默认构造函数。

同样,specific_exception不是默认可构造的,因为它的基类不是。这里你需要一个默认的构造函数,因为它是隐式初始化的基础:

specific_exception(int guilty_object_id_)
    : guilty_object_id(guilty_object_id_) {}

要解决此问题,请调用相应的基类构造函数:

specific_exception(int guilty_object_id_)
    : library_exception("hello, world!"),
      guilty_object_id(guilty_object_id_) {}

答案 1 :(得分:0)

撤消: 这个答案是错误的。 (引用的构造函数实际上用于类成员的默认初始化,而不是类本身。)

std :: runtime_error 有一个字符串字段,如下所示:

class runtime_error {
    std::string msg;

public:
    runtime_error(std::string msg) : msg(msg) { }
};

msg 未由您的构造函数初始化(并且不能,因为该字段是私有的)。因此,将调用默认构造函数。更准确地说,

  

默认初始化[...]是在没有初始化程序的情况下构造变量时执行的初始化。

     

...

     

默认初始化在以下三种情况下执行:

     

...

     

3)在构造函数初始值设定项列表中未提及基类或非静态数据成员且调用该构造函数时。

     

默认初始化的效果是:

     

...

     

如果T是[...]类类型,则考虑构造函数并对空参数列表进行重载解析。选择的构造函数(它是默认构造函数之一)被调用以提供新对象的初始值。

cppreference.com

但是,我仍然不知道它为什么抱怨基类 library_exception 而不是 specific_exception 。在 specific_exception 中添加无参数构造函数并没有什么不同。