【问题标题】:Constructor inheritance and custom constructors构造函数继承和自定义构造函数
【发布时间】:2014-03-20 13:48:27
【问题描述】:

使用这个层次结构:

struct TestBase {
    // Constructor
    TestBase();
    TestBase(int a);
    TestBase(TestBase const &testBase);

    // Destructor
    virtual ~TestBase();
};

struct TestChild : public TestBase {
    // Constructor inheritance
    using TestBase::TestBase;
};

有了这个测试代码:

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 ?

首先我认为在测试4中复制构造函数是从TestBase继承的(通过'using'关键字)但实际上这是因为编译器生成了一个调用父类的复制构造函数的默认复制构造函数,是否正确?

复制构造函数不能被继承,因为它必须与类具有相同的参数类型,是否也正确?

但是为什么测试 5 不能编译?它不是 TestChild 类的复制构造函数,所以它必须被继承,不是吗?


这是错误信息:

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&&’

【问题讨论】:

标签: c++ inheritance c++11


【解决方案1】:

命名构造函数的using-declaration隐式声明了一组继承的构造函数,但值得注意的是,有些构造不是继承的。


标准是怎么说的?

12.9 继承构造函数 [class.inhctor]

3 对于候选继承构造函数集中的每个非模板构造函数,除了没有参数的构造函数或具有单个参数的复制/移动构造函数之外,构造函数被隐式声明具有相同的构造函数特征,除非在出现 using-declaration 的完整类中存在具有相同签名的用户声明构造函数,否则构造函数将是默认、复制或移动该类的构造函数。

上面的句子可能看起来比它实际上更神秘。它的意思是,用简单的英语来说,构造函数仅在 using Base::Base 的上下文中被继承,如果构造函数;

  • 不是模板,而且;
  • 不是默认构造函数(即没有参数),并且;
  • 不是复制/移动构造函数,并且;
  • Derived 中没有与通常从Base 继承的构造函数相匹配的显式声明

结论

考虑到上述情况,我们意识到TestBase 中采用TestBase const& 的构造函数是一个复制构造函数,并且由于复制构造函数不是继承的,这就是它在@987654327 中不存在的原因@。

【讨论】:

    猜你喜欢
    • 2016-03-24
    • 2014-11-22
    • 2011-12-27
    • 2013-06-01
    • 2023-04-03
    相关资源
    最近更新 更多