C++ 继承虚拟派生类的构造函数。

C++ 继承虚拟派生类的构造函数。,c++,inheritance,constructor,virtual,C++,Inheritance,Constructor,Virtual,我遇到了一个问题,这个问题询问它的输出 #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{ publ

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

#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;
}
使用了什么?因为我不是一个班

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

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

第三季度。尽管参数正在初始化,但我们在构造函数中发送的值似乎有所不同。为什么会这样?

ctor初始值设定项列表包含所有子对象的初始值设定项。这意味着基类子对象和成员子对象

子对象总是按照它们在类定义中出现的顺序进行初始化。在ctor初始值设定项列表中放置它们的顺序并不重要,尽管当忽略顺序时,将它们放置在任何其他顺序中都会造成混淆

继承的基子对象构造函数由直接派生的类的构造函数调用。。。虚拟基子对象除外,它直接从最派生对象的构造函数调用。虚拟基子对象是在构建其他对象之前构建的

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

1冒号:可在构造函数中用于调用具有给定参数的成员变量的构造函数:

public:
        int i;
        A(int j=3):i(j){}
意味着A的成员i将调用其构造函数,参数为j

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

class D:public B, public C
3它们没有初始化,被赋予了默认参数。

Q1: 构造函数中介于函数签名和函数体开始括号之前的代码称为初始值设定项列表

初始值设定项列表的语法是具有相应初始值的类的成员变量列表。初始值在括号中。成员变量之间用逗号分隔。第一个变量位于冒号之后

初始值设定项列表还可以包括基类的构造函数,这是B和C类所做的。“A”类只使用初始化成员变量的形式

问题2: 要查找构造函数的执行顺序,请输入一些print语句。它将帮助您了解施工顺序。还可以放入析构函数,并在其中放入print语句。在这个问题上,我不能帮你做所有的家庭作业

问题3: 我猜初始化参数是指默认参数?如果值实际传递到函数中,则默认参数始终被重写

A1.:Aint j=3中的ij:ij{}是初始值设定项列表。初始值设定项列表可以指定如何初始化父类和成员变量。j是i的初始值设定项,其行为类似于局部变量int ij;的初始化;。您可能更熟悉初始化语法int i=j;这是相似的。不能在初始值设定项列表中使用=语法

A2。虚拟基类总是由派生最多的类的构造函数以独占方式初始化。因此,D的构造函数初始化其A基类,当D的构造函数调用B和C的构造函数时,这些构造函数不会重新初始化A


A3。语法Dint j=0不初始化参数。相反,它为参数声明了一个默认值,当您显式传递该参数的值时,该值将被忽略。

ij是初始化i的成员初始化器。我确实放置了print语句,但顺序保持不变。是不是尽管隐式调用构造函数,显式顺序仍然保持不变?
class D:public B, public C