为什么编译器要为我的异常 class 寻找默认构造函数?
Why does the compiler look for a default constructor for my exception class?
我已经为我的库定义了一个小的异常层次结构。它继承自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_) {}
};
编译器说:
error: call to implicitly-deleted default constructor of 'library_exception'
并指向 specific_exception 构造函数。
为什么要在这里尝试调用默认构造函数?
撤回: 这个回答被误导了。 (引用的构造函数实际上用于 class 成员的默认初始化,而不是 class 本身。)
std::runtime_error 有一个字符串字段,像这样:
class runtime_error {
std::string msg;
public:
runtime_error(std::string msg) : msg(msg) { }
};
msg 未由您的构造函数初始化(并且不可能,因为该字段是私有的)。因此调用默认构造函数。更准确地说,
default initialization […] is the initialization performed when a variable is constructed with no initializer.
…
Default initialization is performed in three situations:
…
3) when a base class or a non-static data member is not mentioned in a constructor initializer list and that constructor is called.
The effects of default initialization are:
…
If T is a […] class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object.
但是,我仍然不明白为什么它抱怨基数 class library_exception 而不是 specific_exception。在 specific_exception 中添加无参数构造函数没有任何区别。
library_exception
继承自 std::runtime_error
。后者没有默认构造函数,这意味着前者不可默认构造。
同样,specific_exception
不是默认可构造的,因为它的基础 class 不是。这里需要一个基类的默认构造函数,因为基类是隐式初始化的:
specific_exception(int guilty_object_id_)
: guilty_object_id(guilty_object_id_) {}
要解决此问题,请调用适当的基础 class 构造函数:
specific_exception(int guilty_object_id_)
: library_exception("hello, world!"),
guilty_object_id(guilty_object_id_) {}
我已经为我的库定义了一个小的异常层次结构。它继承自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_) {}
};
编译器说:
error: call to implicitly-deleted default constructor of 'library_exception'
并指向 specific_exception 构造函数。
为什么要在这里尝试调用默认构造函数?
撤回: 这个回答被误导了。 (引用的构造函数实际上用于 class 成员的默认初始化,而不是 class 本身。)
std::runtime_error 有一个字符串字段,像这样:
class runtime_error {
std::string msg;
public:
runtime_error(std::string msg) : msg(msg) { }
};
msg 未由您的构造函数初始化(并且不可能,因为该字段是私有的)。因此调用默认构造函数。更准确地说,
default initialization […] is the initialization performed when a variable is constructed with no initializer.
…
Default initialization is performed in three situations:
…
3) when a base class or a non-static data member is not mentioned in a constructor initializer list and that constructor is called.
The effects of default initialization are:
…
If T is a […] class type, the constructors are considered and subjected to overload resolution against the empty argument list. The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object.
但是,我仍然不明白为什么它抱怨基数 class library_exception 而不是 specific_exception。在 specific_exception 中添加无参数构造函数没有任何区别。
library_exception
继承自 std::runtime_error
。后者没有默认构造函数,这意味着前者不可默认构造。
同样,specific_exception
不是默认可构造的,因为它的基础 class 不是。这里需要一个基类的默认构造函数,因为基类是隐式初始化的:
specific_exception(int guilty_object_id_)
: guilty_object_id(guilty_object_id_) {}
要解决此问题,请调用适当的基础 class 构造函数:
specific_exception(int guilty_object_id_)
: library_exception("hello, world!"),
guilty_object_id(guilty_object_id_) {}