【问题标题】:"using" constructor inheritance c++“使用”构造函数继承 C++
【发布时间】:2021-02-21 19:15:38
【问题描述】:

我有以下代码:

#include <iostream>

using namespace std;

class Base {
    protected:
        char const* name;
        
    public:
        Base(char const* n) : name{n} {
            cout << "Base constructed" << endl;
        }
};

class Color : virtual public Base {
    protected:
        Color(char const* n) : Base(n) {
            cout << "Color constructed" << endl;
        } 
};

class Text : public virtual Base {
    protected:
        Text(char const* n) : Base(n) {
            cout << "text constructed" << endl; 
        }  
};

class NexButton : public Color , public Text {
    public:
        NexButton(char const* n) : Base(n), Color(n), Text(n) {
            cout << "NexButton constructed" << endl;
        } 
};

int main() {
    NexButton btn{"b0"};
}

哪些输出:

Base constructed
Color constructed
text constructed
NexButton constructed

但是下面的代码:

#include <iostream>

using namespace std;

class Base {
    protected:
        char const* name;
        
    public:
        Base(char const* n) : name{n} {
            cout << "Base constructed" << endl;
        }
};

class Color : virtual public Base {
    using Base::Base;
};

class Text : public virtual Base {
    using Base::Base;
};

class NexButton : public Color , public Text {
    using Color::Color;
    using Text::Text;
};

int main() {
    NexButton btn{"b0"};
}

输出:

Base constructed

不明白为什么第二个代码sn-p只输出BaseConstructed;派生类不应该向终端输出一些东西吗?因为他们正在继承构造函数?除了派生类输出到 cout 之外,这两个代码 sn-ps 在很多方面都不是相同的吗? (不相同)

视觉上,为什么没有输出:

Base constructed
Base constructed
Base constructed
Base constructed

【问题讨论】:

  • “派生类不应该也向终端输出一些东西吗?” 不,它不会输出任何东西,除非你告诉它这样做,而不是使用编译器生成的构造函数。
  • 您没有为派生类指定构造函数。您的 4 个 c'tors 仍在被调用,但您的类的“隐式定义的默认构造函数”不打印任何内容。
  • 使用不同于调用。 using 引入构造函数,就好像它们是你自己的一样。您只能以这种方式调用您自己的构造函数之一。但是,没有什么可以阻止您创建自己的构造函数来完全满足您的需求(例如调用或不调用您想要的构造函数)
  • 为什么会调用“隐式定义的默认构造函数”?我正在为构造函数提供一个参数。
  • @N.Prone:如果我是 OP,我不会理解你的评论。请将其扩展为一个答案,准确解释隐式定义了哪些构造函数以及原因。

标签: c++ inheritance using


【解决方案1】:

根据the section on Inheriting ConstructsCppReference.com,当你

use Base::Base;

您将父超类构造函数公开为子类的构造函数。因此,当你写

class Text : public virtual Base { using Base::Base; };

Text 类现在具有以下构造函数:

Text(char const* n) : Base(n) { };

此构造函数打印一行 - Base 类构造函数中的行。 Color 的构造函数也是如此。

好的,那么 - 你为什么不打印 two 行呢?一张给Color,一张给Text

好吧,您对Base 的继承是虚拟的Base 实例是直接从NextButton 构造的,而不是从两个超类构造函数中一次又一次地构造。因此 - 只需打印一次。

您可能还想阅读:

Order of constructor call in virtual inheritance

在这里。


其他建议:

  • 请避免using namespace std;是bad practice
  • 您有一个char const * n 参数。 n 是一个糟糕的名称选择,因为 n 通常用于数字(number 或 natural number);如此之多,以至于很多人可能会忘记您的 n 应该是 C 风格的字符串。

【讨论】:

    猜你喜欢
    • 2019-01-21
    • 2012-11-14
    • 2021-06-24
    • 2015-03-24
    • 2014-08-21
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多