C ++ Primer(第5版)第629页声明:
我为自己尝试了这个,对我而言,编译器生成的派生构造函数似乎也具有与基本构造函数相同的默认参数。
这是一个小小的考验:
#include <iostream>
struct Base
{
Base() = default;
Base(int x_, int y_ = 88, int z_ = 99)
: x(x_), y(y_), z(z_) {}
virtual void debug() const
{ std::cout << "\nx - " << x << ", y - " << y << ", z - " << z << '\n'; }
private:
int x, y, z;
};
struct Derived : Base
{
using Base::Base;
};
int main() {
Base B(1);
B.debug(); // x - 1, y - 88, z - 99
Derived D(5);
D.debug(); // x - 5, y - 88, z - 99
return 0;
}
(你可以在这里运行 - http://coliru.stacked-crooked.com/a/26cbb85757c1f021)
左,我们是否继承了继承构造函数的默认参数?
如果没有,为什么我没有为最后2个成员获取垃圾,但是与从base继承的构造函数的默认参数相同的确切值?
还在互联网上搜索了关于此的明确答复,但没有找到。
答案 0 :(得分:8)
你对这本书的引用并不完整。
如果基类构造函数具有默认参数(第6.5.1节,第236页),那么这些参数 不是继承的。相反,派生类获取多个继承的构造函数 其中每个参数都有一个默认参数被连续省略。例如,如果 base有一个带有两个参数的构造函数,第二个参数有一个默认值, 派生类将获得两个构造函数:一个具有两个参数(并且没有 默认参数)和第二个构造函数,其中一个参数对应于 基类中最左边的非默认参数
因此,您的Derived类将具有3个具有签名的继承构造函数:
Derived (int x): Base{x} {}
Derived (int x, int y): Base{x, y} {}
Derived (int x, int y, int z): Base{x, y, z} {}
所以你不继承基类的任何默认参数。
Derived D(5);
调用上面三个构造函数中的第一个,并且像
一样调用基础构造函数Base(5)
另请注意,默认,复制和移动构造函数不是 遗传。这些构造函数使用常规规则合成。一个继承的 构造函数不被视为用户定义的构造函数。因此,一类 仅包含继承的构造函数将具有合成的默认构造函数。
答案 1 :(得分:6)
来自[class.inhctor]:
在 来自使用声明中命名的类X的继承构造函数的候选集包含实际 由默认参数转换产生的构造函数和名义构造函数 省略号参数规格如下:
- [...]
- 对于X的每个非模板构造函数,该构造函数至少有一个带有默认参数的参数,即该集合 省略任何省略号参数规范和连续省略的构造函数 参数类型列表末尾带有默认参数的参数和
- [...]
我们有两个Base
的非模板构造函数。 Base
的默认构造函数引入了候选项:
Derived() : Base() { }
Base
的另一个构造函数为每个连续省略的参数引入了一个候选者。即:
Derived(int x, int y, int z) : Base(x, y, z) { }
Derived(int x, int y) : Base(x, y) { }
Derived(int x) : Base(x) { }
默认参数是而不是继承 - 我们只为每个参数提供不同的构造函数。因此Derived(5)
只需拨打Base(5)
,而不是Base(5, 88, 99)
。
最终结果是一样的 - 我们如何到达那里有点不同。