繁体   English   中英

继承类的构造函数实际上是派生的。

[英]inheriting constructors of class virtually derived.

我遇到了这个问题,询问它的输出。

#include<iostream>
using namespace std;
class A{
      public:
            int i;
            A(int j=3):i(j){}
};
class B:virtual public A{
      public:
            B(int j=2):A(j){}
};
class C:virtual public A{
      public:
            C(int j=1):A(j){}
};
class D:public B, public C {
      public:
            D(int j=0):A(j), B(j+1), C(j+2){}
};
int main()
{
D d;
cout<<d.i;
return 0;
}

有几件事我不理解。 请澄清这些疑问。由于我不知道要搜索什么,因此我无法对其进行搜索。

Q1。 就像在代码中使用参数化的构造函数一样,在冒号(:)之后,我们编写了父类的构造函数。

A(int j=3):i(j){}

用来? 由于我不是一个班级。

Q2。 在类D中,类的构造函数使用构造函数初始化基类,但是可以看出,所有构造函数仅修改类A的变量i。 那么构造函数在这里调用的顺序是什么。

我知道当我们不调用父类的构造函数时,会显式调用它,并且顺序是众所周知的,但是当我们像这里这样隐式调用构造函数时会怎样。

Q3。 尽管初始化了参数,但我们在构造函数中发送的值似乎有所不同,为什么呢?

A1。 :i(j)A(int j=3):i(j){}是一个初始化列表。 初始化程序列表可以指定如何初始化父类成员变量。 (j)i的初始化程序,其行为类似于局部变量的初始化: int i(j); (您可能更熟悉int i = j;的初始化语法int i = j;这很相似。您不能在初始化列表中使用=语法。)

A2。 虚拟基类始终由大多数派生类的构造函数专门初始化。 因此, D的构造函数初始化其A基类,并且D的构造函数调用BC的构造函数时,这些构造函数不会重新初始化A

A3。 语法D(int j=0)不会初始化参数。 而是为该参数声明一个默认值 ,只要您显式传递该参数的 ,该默认值就会被忽略。

ctor-initializer-list包含所有子对象的初始化程序。 这意味着基类的子对象和成员的子对象。

子对象总是按照它们在类定义中出现的顺序进行初始化。 将它们放在ctor-initializer-list中的顺序无关紧要(尽管忽略它们时,以其他任何顺序将它们混淆)。

继承的基础子对象构造函数由直接派生的类的构造函数调用...除了虚拟基础子对象之外,虚拟基础子对象直接从生成最多的对象的构造函数中调用。 虚拟基础子对象首先构建。

没有“正在初始化参数”这样的事情。 这些是默认参数 ,提供实际参数时将忽略它们。

1)冒号:可以在构造函数中使用,以给定参数调用成员变量的构造函数:

public:
        int i;
        A(int j=3):i(j){}

表示A的成员i将使用j作为参数调用其构造函数。

2)子对象将按照它们在类定义中出现的顺序进行初始化

class D:public B, public C

3)它们没有被初始化,而是被赋予默认参数。

问题1:构造函数中函数签名之间和函数主体左括号之间的代码称为初始化列表。

初始化程序列表的语法是具有相应初始值的类的成员变量列表。 初始值在括号中。 成员变量由逗号分隔。 第一个变量在冒号之后。

初始化程序列表还可以包含基类的构造函数,这是您的B和C类所做的。 您的“ A”类仅使用初始化成员变量的形式。

Q2:要查找执行构造函数的顺序,请放入一些print语句。 它将帮助您了解构造顺序。 还要放入析构函数,并在其中放入打印语句。 在这个问题上,我无法为您完成所有作业。 :)

Q3:我想通过初始化参数来表示默认参数? 如果实际将值传递到函数中,则始终会覆盖默认参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM