继承默认构造函数,矛盾吗?

Posted

技术标签:

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

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

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

但另一方面:

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

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

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

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

【问题讨论】:

【参考方案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 基数。

【讨论】:

以上是关于继承默认构造函数,矛盾吗?的主要内容,如果未能解决你的问题,请参考以下文章

关于java中子类继承父类的构造方法

子类可以继承父类的啥

子类可以继承父类的啥

在构造函数继承中使用默认构造函数

C++中,继承时,创建子类对象,能否在子类构造函数初始化列表里调用基类构造函数?

子类继承父类的构造函数(方法)吗?