为什么在此代码中必须使用Child传递构造函数?我认为它不会,但编译器(gcc和VS2010)在我删除它时会抱怨。有优雅的解决方法吗?将这个垫片插入子类似乎毫无意义。
class Parent
{
public:
Parent(int i) { }
};
class Child : public Parent
{
public:
Child(int i) : Parent(i) { }
};
int main()
{
Child child(4);
return 0;
}
答案 0 :(得分:12)
因为以下内容完全有效:
class Parent
{
public:
Parent(int i) { }
};
class Child : public Parent
{
public:
Child() : Parent(42) { }
};
编译器如何猜测您是否希望派生子进程具有转发构造函数?在多重继承的情况下,两种类型的构造函数集可能不匹配;从基类A转发构造函数时,应该调用基类B上的构造函数吗?
从技术上讲,我认为语言设计者可以说如果类型有一个基类并且没有显式构造函数,那么所有父构造函数都会被转发。但是,这会产生相反的问题:如果基类有多个构造函数,包括默认构造函数,并且子程序只希望允许默认构造函数,那么现在必须明确指定它。
答案 1 :(得分:4)
如果没有指定应该显式调用哪个父构造函数,编译器将生成调用默认(无参数或所有默认值)构造函数的代码。
在您的情况下,类Parent
没有这样的构造函数,编译器不知道i
使用什么值。
未在类Child
中指定构造函数意味着将调用类Parent
中的默认构造函数,但这不存在。
我没试过,但看看this section of the C++0x FAQ。我有一个印象,你要求的是C ++ 0x。
答案 2 :(得分:3)
这是因为在C ++中你有多重继承。在下面的示例中,应该继承哪个构造函数?
class Parent1
{
public:
Parent1(int i) { }
};
class Parent2
{
public:
Parent2(int i) { }
};
class Child : public Parent1, public Parent2
{
};
答案 3 :(得分:1)
这是另一个案例
class Parent
{
public:
Parent(int i) {this.i = i; }
Parent() {this.i = 0;}
private:
int i;
};
class Child : public Parent
{
public:
Child(int i) : { }
};
int main()
{
Child child(4);
return 0;
}
鉴于此,应该调用哪个Parent
构造函数。如果Parent
定义了一个接纳long
但不接受int
的构造函数,该怎么办?编译器应该自动将int
转换为long
吗?
无论好坏,语言设计者都选择了简单性 - 从派生类中自动调用的唯一构造函数是默认值(no-arg或所有具有默认值的args)构造函数。其他所有东西都需要明确调用。
答案 4 :(得分:1)
有优雅的解决方法吗?
从C ++ 11开始,您可以使用using declaration从基类继承构造函数(不包括默认,复制或移动构造函数):
class Parent
{
public:
Parent(int i) { }
};
class Child : public Parent
{
public:
using Parent::Parent; // inherits Parent(int)
};
int main()
{
Child child(4);
return 0;
}
答案 5 :(得分:0)
编译器只自动生成默认构造函数,即没有参数的ctr,但前提是你没有定义任何构造函数。
在这种情况下,你有(在父级中),所以没有为你做出默认,加上孩子需要它,以便它知道如何处理你传递给它的参数i
。
答案 6 :(得分:0)
如果您不想使用由编译器生成的默认构造函数(称为默认构造函数(没有参数的构造函数)),则构造函数需要由子构造函数显式调用。但显然在你的情况下你需要一个接受int
的构造函数,那么你必须明确地调用它。