为什么 C++构造函数继承?
为什么这段代码中需要 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;
}
Why is the Child pass-through constructor necessary in this code? I would think that it wouldn't be, but the compiler (gcc and VS2010) complains when I remove it. Is there an elegant workaround? It just seems pointless to have to insert this shim into child classes.
class Parent
{
public:
Parent(int i) { }
};
class Child : public Parent
{
public:
Child(int i) : Parent(i) { }
};
int main()
{
Child child(4);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
因为以下内容完全有效:
编译器如何猜测您是否希望派生子级具有转发的构造函数?在多重继承的情况下,两种类型的构造函数集可能不匹配;当从基类 A 转发构造函数时,应该调用基类 B 上的哪个构造函数?
从技术上讲,我想语言设计者可能会说,如果类型具有单个基类并且在没有显式构造函数的情况下,则转发所有父构造函数。但是,这会产生相反的问题:如果基类具有多个构造函数(包括默认构造函数),并且子类希望仅允许使用默认构造函数,则现在必须显式指定它。
Because the following is perfectly valid:
How is the compiler to guess whether you want the derived child to have a forwarded constructor? And in the case of multiple inheritance, the set of constructors from the two types may not match; when forwarding a constructor from base class A, which constructor on base class B should be called?
Technically, I suppose the language designers could have said that if the type has a single base class and in the absence of an explicit constructor, all parent constructors are forwarded. However, that creates the opposite problem: if a base class has multiple constructors including a default constructor, and the child wishes to allow only the default constructor, this must now be explicitly specified.
如果您没有显式指定应调用哪个父构造函数,编译器将生成调用默认(无参数或使用所有默认值)构造函数的代码。
在您的情况下,类
Parent
没有这样的构造函数,编译器将不知道i
使用什么值。在类
Child
中未指定构造函数意味着将调用类Parent
中的默认构造函数,但该构造函数不存在。我还没有尝试过,但看看 这一部分C++0x 常见问题解答。我的印象是你所要求的在 C++0x 中是可能的。
If you don't specify which parent constructor should be called explicitly, the compiler will generate code which calls the default (no-argument or with all default values) constructor.
In your case, the class
Parent
does not have such a constructor, the compiler would not know what value to use fori
.Not specifying a constructor in class
Child
means that the default constructor in classParent
would be called but this does not exist.I haven't tried it but have a look at this section of the C++0x FAQ. I have the impression what you're asking for is possible in C++0x.
这是因为在 C++ 中你有多重继承。在下面的例子中,哪个构造函数应该被继承?
It's because in C++ you have multiple inheritance. In the following example, which constructor should be inherited?
从 C++11 开始,您可以使用 using 声明 来继承来自基类的构造函数(不包括默认、复制或移动构造函数):
Since C++11, you can use a using declaration to inherit constructors (not including default, copy or move constructors) from a base:
这是另一种情况
,鉴于此,应该调用哪个
Parent
构造函数。如果Parent
定义了一个接受long
的构造函数,而不是接受int
的构造函数,该怎么办?编译器是否应该自动将int
转换为long
?无论好坏,语言设计者选择了简单性——从派生类自动调用的唯一构造函数是默认(无参数或所有参数都有默认值)构造函数。其他一切都需要显式调用。
Here's another case
Given that, which
Parent
constructor should be called. What ifParent
defines a constructor that takes in along
but not one that takes anint
? Should the compiler auto-convert theint
tolong
?For better or worse, the language designers opted for simplicity -- the only constructor that is automatically called from a derived class is the default (no-arg or all args having defaults) constructor. Everything else needs to be explicitly called.
编译器仅自动生成默认构造函数,即不带参数的 ctr,但前提是您尚未定义任何构造函数。
在这种情况下,您有(在父级中),因此不会为您设置默认值,而且子级需要它,以便它知道如何处理您传递给它的参数
i
。The compiler only autogenerates the default constructor, that is the ctr without parameters, but only if you haven't defined any constructors.
In this case, you have (in the parent), so no default is made for you, plus the child needs it so that it knows what to do with the parameter
i
that you are passing to it.如果您不想使用编译器生成的默认构造函数,则需要由子构造函数显式调用构造函数,该默认构造函数称为默认构造函数(不带参数的构造函数)。但显然在您的情况下,您需要一个接受
int
的构造函数,然后您必须显式调用它。Constructors need to be called explicitly by the child constructor if you don't want to use the default one which generated by compiler, which is called default constructor (the one with no arguments). But apparently in your case you want a constructor that accepts an
int
, then you have to call it explicitly.