使用此层次结构:
struct TestBase { //构造函数 TestBase TestBase(int a); TestBase(TestBase const& testBase); //析构函数 virtual〜TestBase(); }; struct TestChild:public TestBase { //构造方法继承使用TestBase :: TestBase; };使用此测试代码:
TestBase testBase; // 1)自定义构造函数 TestChild testChild; // 2)编译器创建的默认构造函数 TestChild testChild2(1); // 3)从parent继承'using'关键字 TestChild testChild3(testChild); // 4)编译器创建的默认复制构造函数? TestChild testChild4(testBase); // 5)不工作,为什么它不继承?
首先我想在测试4中构造函数继承自TestBase(通过'using'关键字),但实际上是因为编译器生成一个默认的拷贝构造函数,它调用父类的拷贝构造函数,是否正确?
复制构造函数不能被继承,因为它必须具有与类相同的参数类型,是否正确?
但是为什么测试5不会编译?它不是TestChild类的复制构造函数,所以它必须继承,不是?
这是错误消息: / p>
foo.cpp:在函数'int main()': foo.cpp :21:34:error:没有匹配函数调用'TestChild :: TestChild(TestBase&)' TestChild testChild4(testBase); // 5)不工作,为什么它不继承? ^ foo.cpp:21:34:注意:候选人是: foo.cpp:11:12:note:TestChild :: TestChild() struct TestChild:public TestBase { ^ foo.cpp:11:12:note:candidate期望有0个参数,1个提供 foo.cpp:13:25:note:TestChild :: TestChild b $ b使用TestBase :: TestBase; ^ foo.cpp:13:25:注意:没有从'TestBase'到'int'的参数1的已知转换 foo.cpp:11:12:note:TestChild :: TestChild(const TestChild&) struct TestChild:public TestBase { ^ foo.cpp:11:12:注意:没有从'TestBase'到'const TestChild& ' foo.cpp:11:12:note:TestChild :: TestChild(TestChild&&) foo.cpp:11:12:注意:没有从'TestBase' 'TestChild&'解决方案
-declaration 名称的构造函数隐式声明一组继承的构造函数,但值得注意的是,有一些结构是不继承的。
标准说了什么?12.9 继承构造函数 [class.inhctor]
3 除了没有参数的构造函数或具有单个参数的复制/移动构造函数之外的候选继承构造函数集合中的每个非模板构造函数,构造函数以相同构造函数特性隐式地声明,除非存在用户 - 在出现 using-declaration 的完整类中具有相同签名的声明构造函数,或者构造函数是该类的默认,复制或移动构造函数。
上面的句子可能看起来更加神秘,它实际上是..它在说,在简单的英语,是一个构造函数只继承在的上下文中使用Base :: Base 如果构造函数;
- isn' t a template,and;
- 不是默认构造函数(即。没有参数)和;
- 不是复制/移动构造函数,
- 在 Derived 匹配通常从 Base继承的构造函数
考虑到上述情况,我们意识到 TestBase ,它需要一个 TestBase const& 是一个复制构造函数,并且由于复制构造函数不被继承,这是它不存在于 TestChild 。
Using this hierarchy :
struct TestBase { // Constructor TestBase(); TestBase(int a); TestBase(TestBase const &testBase); // Destructor virtual ~TestBase(); }; struct TestChild : public TestBase { // Constructor inheritance using TestBase::TestBase; };With this test code :
TestBase testBase; // 1) Custom constructor TestChild testChild; // 2) Default constructor created by the compiler TestChild testChild2(1); // 3) Inherited from parent with 'using' keyword TestChild testChild3(testChild); // 4) Default copy constructor created by the compiler ? TestChild testChild4(testBase); // 5) Doesn't work, why it doesn't inherit ?
First I was thinking that in test 4 the copy constructor was inherited from TestBase (by the 'using' keyword) but in fact it's because the compiler generates a default copy constructor which calls copy constructor of the parent class, is it correct ?
A copy constructor can't be inherited because it must have the same parameter type than the class, is it correct too ?
But why test 5 doesn't compile ? It's not a copy constructor for the TestChild class so it must be inherited, no?
This is the error message:
foo.cpp: In function ‘int main()’: foo.cpp:21:34: error: no matching function for call to ‘TestChild::TestChild(TestBase&)’ TestChild testChild4(testBase); // 5) Doesn't work, why it doesn't inherit ? ^ foo.cpp:21:34: note: candidates are: foo.cpp:11:12: note: TestChild::TestChild() struct TestChild : public TestBase { ^ foo.cpp:11:12: note: candidate expects 0 arguments, 1 provided foo.cpp:13:25: note: TestChild::TestChild(int) using TestBase::TestBase; ^ foo.cpp:13:25: note: no known conversion for argument 1 from ‘TestBase’ to ‘int’ foo.cpp:11:12: note: TestChild::TestChild(const TestChild&) struct TestChild : public TestBase { ^ foo.cpp:11:12: note: no known conversion for argument 1 from ‘TestBase’ to ‘const TestChild&’ foo.cpp:11:12: note: TestChild::TestChild(TestChild&&) foo.cpp:11:12: note: no known conversion for argument 1 from ‘TestBase’ to ‘TestChild&&’解决方案
A using-declaration that names a constructor implicitly declares a set of inherited constructors, but what is worth noting is that there are certain constructs which are not inherited.
What does the standard say?12.9 Inheriting Constructors [class.inhctor]
3 For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy ,or move constructor for that class.
The above sentence might look more cryptic that it actually is.. what it is saying, in simple english, is that a constructor is only inherited in the context of using Base::Base if the constructor;
- isn't a template, and;
- isn't a default constructor (ie. having no parameters), and;
- isn't a copy/move constructor, and;
- there's no explicit declaration in Derived that matches a constructor normally inherited from Base
With the above in mind we realize that the constructor in TestBase that takes a TestBase const& is a copy-constructor, and since copy-constructors are not inherited, that's the reason for it being non-present in TestChild.
更多推荐
构造函数继承和自定义构造函数
发布评论