【问题标题】:Not able to understand virtual base class constructor in case of multilevel inheritance在多级继承的情况下无法理解虚拟基类构造函数
【发布时间】:2016-11-23 05:04:58
【问题描述】:

在下面的程序中,如果我更改派生类“D”中的序列,那么我会得到基类构造函数的不同顺序。

    #include <iostream>

    using namespace std;

    class A {
      public :
            A ()
            {
                cout << "A()" <<endl;
            }
    };

    class B : virtual A{
      public :
            B ()
            {
                cout << "B()" << endl;
            }
    };

    class C : virtual B{
      public :
            C ()
            {
                cout << "C()" << endl;
            }
    };

Case (1)
========
    class D : public A, public B, public C
    {

    };

    int main()
    {
        D d;
        return 0;
    }
OUTPUT : 
A()
B()
A()
B()
C()

Case (2)
========
    class D : public C, public B, public A
    {

    };

    int main()
    {
        D d;
        return 0;
    }
OUTPUT :
A()
B()
C()
B()
A()

Case (3)
========
    class D : public B, public A, public C
    {

    };

    int main()
    {
        D d;
        return 0;
    }
OUTPUT :
A()
B()
B()
A()
C()

请任何人告诉我们在虚拟类概念的情况下如何调用构造函数。

【问题讨论】:

  • 不确定您是否了解虚拟继承的工作原理:ideone.com/Ptaf5u
  • 为什么要使用私有继承?

标签: c++ constructor multiple-inheritance virtual-inheritance


【解决方案1】:

请任何人告诉我们在虚拟类概念的情况下如何调用构造函数。

根据initialization order,首先会初始化虚拟基类。

1) 如果构造函数用于最派生类,则虚拟基类 类按照它们出现的顺序进行初始化 基类声明的深度优先从左到右遍历 (从左到右指的是在基本说明符列表中的出现)

2) 然后,直接基类按从左到右的顺序初始化为 它们出现在此类的基本说明符列表中

3) 然后,非静态数据成员按顺序初始化 类定义中的声明。

4) 最后执行构造函数的主体

在所有3种情况下,类D继承自ABCD中有两个虚拟基类,即A继承自BC,以及B 通过C 继承。而A会首先被初始化,因为它是最基类,所以对于所有3种情况,A()B()都会首先被打印出来。

之后,直接基类将以从左到右的顺序初始化。第一种情况为A()B()C(),第二种情况为B()C()A(),第三种情况为B()A() C().

【讨论】:

    【解决方案2】:

    虚拟基地总是在 DFS 后序中首先初始化。这保证了虚拟 A 和 B 基将首先被初始化,并且 A 在 B 之前被初始化,因为 B 是从 A 派生的。之后,三个非虚拟基 A、B、C 将按照您所期望的声明顺序简单地初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-24
      • 2012-07-10
      • 2015-06-21
      • 2012-12-19
      • 1970-01-01
      • 2023-04-10
      • 2012-05-19
      • 1970-01-01
      相关资源
      最近更新 更多