【问题标题】:inheriting constructors of class virtually derived.继承虚拟派生类的构造函数。
【发布时间】:2012-12-19 10:52:28
【问题描述】:

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

#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;
}

我不明白的事情很少。 请澄清这些疑问。我无法谷歌搜索,因为我不知道要搜索什么。

第一季度。在代码中使用了参数化构造函数。在冒号(:)之后我们编写父类的构造函数。如何

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

用过吗?因为我不是一个班级。

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

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

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

【问题讨论】:

  • i(j) 是一个初始化 i 的成员初始化器。

标签: c++ inheritance constructor virtual


【解决方案1】:

A1。 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) 不会初始化参数。相反,它为参数声明一个默认值,当您显式传递该参数的值时,该参数将被忽略。

【讨论】:

    【解决方案2】:

    第一季度: 构造函数中函数签名和函数体左括号之前的代码称为初始值设定项列表。

    初始化列表的语法是类的成员变量的列表以及相应的初始值。初始值在括号中。成员变量用逗号分隔。第一个变量出现在冒号之后。

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

    第二季度: 要查找构造函数的执行顺序,请输入一些打印语句。它将帮助您了解构建顺序。还要放入一个析构函数并将打印语句也放入其中。在这个问题上,我不能为你做所有的功课。 :)

    第三季度: 我猜参数被初始化是指默认参数吗?如果实际将值传递给函数,则始终会覆盖默认参数。

    【讨论】:

    • 我确实放了打印语句,但顺序保持不变。是不是尽管隐式调用构造函数,但显式顺序保持不变?
    【解决方案3】:

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

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

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

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

    class D:public B, public C
    

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

    【讨论】:

      【解决方案4】:

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

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

      继承的基子对象构造函数由直接派生的类的构造函数调用...除了虚拟基子对象,它们直接从最派生对象的构造函数调用。虚拟基础子对象是在其他任何东西之前构建的。

      没有“正在初始化的参数”之类的东西。这些是默认参数,当提供实际参数时它们会被忽略。

      【讨论】:

        猜你喜欢
        • 2015-06-21
        • 1970-01-01
        • 2013-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-03
        • 1970-01-01
        • 2020-10-26
        相关资源
        最近更新 更多