构造函数继承和自定义构造函数 [英] Constructor inheritance and custom constructors

查看:184
本文介绍了构造函数继承和自定义构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用此层次结构:

  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 的完整类中具有相同签名的声明构造函数,或者构造函数是该类的默认,复制或移动构造函数。


< blockquote>

上面的句子可能看起来更加神秘,它实际上是..它在说,在简单的英语,是一个构造函数只继承在的上下文中使用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

Conclusion

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.

这篇关于构造函数继承和自定义构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆