虚拟继承中构造函数调用的顺序是什么?

时间:2016-05-15 06:52:11

标签: c++ inheritance virtual

c ++中虚拟继承中构造函数调用的顺序是什么?

对于以下两种多重继承的情况;

(I)以下代码,没有虚拟继承;

class a
{
    public: 

        a()
        {
            cout<<"\t a";
        }

};

class b: public a
{
    public:
        b()
        {
            cout<<"\t b";
        }

};

class c: public b
{
    public:

        c()
        {
            cout<<"\t c";
        }

};

class d: public c
{
    public:

        d()
        {
            cout<<"\t d";
        }
};

class e: public c, public d
{
    public:

        e()
        {
            cout<<"\t e";
        }
};

class f: public b, public e
{
    public:

        f()
        {
            cout<<"\t f";
        }
};


int main()
{

    f aaa;

    return 0;
}

输出结果为:

     a       b       a       b       c       a       b       c       d       e       f

(II)使用类e的虚拟继承:

class a
{
    public: 

        a()
        {
            cout<<"\t a";
        }

};

class b: public a
{
    public:
        b()
        {
            cout<<"\t b";
        }

};

class c: public b
{
    public:

        c()
        {
            cout<<"\t c";
        }

};

class d: public c
{
    public:

        d()
        {
            cout<<"\t d";
        }
};

class e: public c, public d
{
    public:

        e()
        {
            cout<<"\t e";
        }
};

class f: public b, public virtual e
{
    public:

        f()
        {
            cout<<"\t f";
        }
};


int main()
{

    f aaa;

    return 0;
}

输出结果为:

     a       b       c       a       b       c       d       e       a       b       f

有人可以解释在两种情况下如何获得输出? 虚拟继承如何影响对象的构造?

1 个答案:

答案 0 :(得分:3)

首先初始化虚拟基类,否则,直接基类将按基类声明的从左到右的顺序初始化。

对于课程fclass f: public b, public e,没有虚拟基类,直接基类b将首先初始化,然后e。 (从左到右的顺序)

对于class f: public b, public virtual e,虚拟基类e将首先初始化,然后b

请参阅Initialization order

  

1)如果构造函数是针对派生程度最高的类的虚拟基础   类按它们出现的顺序初始化   基类深度优先从左到右遍历基类声明   (从左到右指的是基本说明符列表中的外观)

     

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

     

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

     

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