继承虚派生类的构造函数

inheriting constructors of class virtually derived.

本文关键字:构造函数 派生 继承      更新时间:2023-10-16

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

#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。那么这里调用的构造函数的顺序是什么呢?

我知道当我们不调用父类的构造函数时,它是显式调用的,顺序是众所周知的,但是当我们隐式调用构造函数时呢?

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

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

A2。虚基类总是由最派生类的构造函数独占地初始化。因此D的构造函数初始化了它的A基类,当D的构造函数调用BC的构造函数时,这些构造函数不会重新初始化A

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

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

子对象总是按照它们在类定义中出现的顺序初始化。不管你把它们放在元素-初始化器-列表中的顺序是什么(尽管当顺序被忽略时,把它们放在任何其他顺序都会引起混淆)。

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

没有"参数被初始化"这回事。这些都是默认参数,当提供实际参数时将忽略它们。

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

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

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

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

class D:public B, public C

Q1:构造函数中位于函数签名之间和函数体左括号之前的代码称为初始化列表。

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

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

第二季:要查找构造函数执行的顺序,可以输入一些print语句。它会帮助你理解施工的顺序。同时也放入一个析构函数,并在其中放入print语句。关于这个问题,我不能帮你做所有的作业。:)

第三季度:我猜你说的初始化参数是指默认实参?如果一个值被实际传递到函数中,默认参数总是会被覆盖。