【问题标题】:inheriting default constructor, a contradiction?继承默认构造函数,矛盾吗?
【发布时间】:2020-06-09 22:28:48
【问题描述】:

在 C++(继承主题)中我读到:

派生类自动有一个默认构造函数,一个副本 构造函数和赋值运算符,就像任何其他类一样。这 编译器生成的默认构造函数调用基类默认值 构造函数

但另一方面:

基类构造函数不是继承我们必须显式 定义派生类需要的任何构造函数

1)继承构造函数是什么意思?

2)上面写的不是矛盾吗?

如果可能的话,我希望添加一些例子来帮助我理解。

【问题讨论】:

    标签: c++ class inheritance constructor


    【解决方案1】:

    “基类构造函数不被继承”意味着在类Base 中定义的任何构造函数都不能用于派生类Derived,除非它在Derived 中重新定义。这对默认构造函数也有效。但是,“派生类自动具有默认构造函数”表示编译器将自动生成默认构造函数,就像它为每个类所做的那样。所以编译器会在派生类中重新定义一个默认构造函数;它仍然没有被继承。

    唯一的问题是“我们必须显式定义派生类所需的任何构造函数”,如果没有上下文可以支持该语句,则似乎是错误的。派生类中肯定有可用的构造函数明确地定义。这可以通过定义没有任何显式构造函数的派生类来轻松展示:

    struct Base {
        Base () { std::cout << "in default constructor of Base; not inherited, but still called." << std::endl; };
    };
    
    struct Derived : public Base {
       // no explicitly defined constructor...
    };
    
    int main() {
        Derived d;
    }
    

    输出:

    in default constructor of Base; not inherited, but still called.
    

    所以我倾向于说你引用的“......我们必须明确定义派生类需要的任何构造函数”这句话要么不准确,要么没有在完整的上下文中显示,要么是错误的。

    【讨论】:

    • 但是为什么说“我们必须明确定义派生类需要的任何构造函数”
    • 因为基类构造函数没有被继承。如果你不定义它们,没有人会定义它们。编译器不会从基类定义构造函数。
    • 你说得对,“明确”听起来很矛盾;我认为“他们”省略了“派生类需要,除非这些构造函数是由编译器隐式定义的”。顺便说一句:“他们”是谁?它是一些规范的来源吗? ——
    • 但是为什么我需要写一个构造函数而“派生类自动有一个默认构造函数”,它的工作是什么?我认为它调用了父类的构造函数
    • 好的,谢谢,但是调用父类的构造函数和继承它有什么区别呢?和我想的一样……
    【解决方案2】:
    struct s {
        s() : s_str("my string") {}; // default constructor
        std::string s_str;
    };
    
    struct d : s {
        std::string d_str;
    };
    

    如果d 没有任何需要构造的成员,默认构造函数将简单地构造ss::s(),表面上看起来像继承(并且可以以这种方式实现)。但是,当您将数据成员添加到派生类时,这将不起作用。

    s 的默认构造函数使用文本 "my string" 构造 s_str

    如果s::s()d 继承,它不会知道d_str,所以不会构造它。所以它不是继承的。

    相反,编译器为d 生成一个默认构造函数,该构造函数使用std::string 的默认构造函数构造d_str,并使用s::s() 构造s 基数。

    【讨论】:

      猜你喜欢
      • 2016-03-24
      • 2017-10-04
      • 2015-07-09
      • 2011-05-20
      • 1970-01-01
      • 2016-06-17
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      相关资源
      最近更新 更多