C++为什么基类/结构构造函数不能有多个参数可以从派生隐式调用?
为什么这不起作用:
struct Base {
Base(int a, int b) {}
};
struct Derived: Base {
// using Base::Base; // unless I add this
};
int main() {
Derived d(0, 0);
}
虽然这可以:
struct Base {
Base(int a) {}
};
struct Derived: Base {
// using Base::Base; // without this line
};
int main() {
Derived d(0);
}
注意:C++20 GCC 10.2(第二个示例也不适用于 C++17)
C++20 中第二个例子背后的魔力是什么?
回答
“神奇”在于您不小心使用了聚合初始化。在 C++20(而不是之前)中,您可以通过使用括号而不是大括号来调用聚合初始化,只要不会调用实际的构造函数(如复制/移动构造函数)。这样做是为了允许间接构造类型(emplace、optional的就地构造函数make_shared/unique等)以处理聚合类型。
您的类型Derived是一个聚合,因为它没有用户提供的构造函数和一个子对象(基类)。因此,您使用构造函数语法将调用聚合初始化,第一个聚合成员是基类。可以从int(顺便说一句,explicit除非它们是复制/移动构造函数,否则不从单个参数创建构造函数通常是不好的形式)。
一般来说,除非你打算创建一个聚合(即:类型只是一个任意的值包),派生类应该有构造函数。我不记得我何时编写了一个没有至少一个构造函数的派生类。如果您希望派生类具有基类构造函数,那么您应该在任何时候明确说明这一点。没有明确的声明,构造函数不会被继承。