虚拟继承时的C ++构造函数顺序

时间:2019-05-24 22:44:30

标签: c++ inheritance virtual-inheritance

class Animal {
public:
    Animal(const char * color, int childs, float avgLifetime) {
        //Do something
    }
};

class Birds: virtual public Animal {
public:
    Birds(const char * color, int childs, float avgLifetime, float incubation)
    : Animal(color, childs, avgLifetime) {
        //Do something
    }
};

class Flamingo: public Birds {
public:
    Flamingo(const char * color, int childs, float avgLifetime, float incubation, float avgHeight)
    : Animal(color, childs, avgLifetime),
      Birds(color, childs, avgLifetime, incubation) {
        //Do something
    }
};

当我尝试创建新的Flamingo时,我跳过了Animal构造函数。
我猜是因为Birds是虚拟Animal的继承人。

我认为它将按顺序到达:

Animal->Birds->Flamingo  

为什么它跳过Animal构造函数?

2 个答案:

答案 0 :(得分:2)

由于Birds使用Animal的虚拟继承,所以Birds的任何派生也使用Animal的虚拟继承。特别是:

class Flamingo : public Birds { /* ... */ };

隐式等效于:

class Flamingo : virtual Animal, public Birds { /* ... */ };

如果您是明确编写的,那么您应该向Flamingo添加代码以调用Animal上的构造函数(或允许Flamingo隐式调用{{1} }的默认构造函数)。此外,AnimalFlamingo实例的初始化会覆盖Animal'。

因此,初始化仍然是BirdsAnimalBirds,但是Flamingo初始化是Animal所做的,而Flamingo 'Birds已被初始化,因此跳过初始化。

答案 1 :(得分:0)

对于虚拟基础,它是调用虚拟基础构造函数的派生程度最高的类。

所以在您的情况下:

class Flamingo: public Birds {
public:
    Flamingo(const char* color,
             int childs,
             float avgLifetime,
             float incubation,
             float avgHeight) :
        // Animal(), // it is this one which is called
        Birds(color, childs, avgLifetime, incubation)
    {}
    // ...
};

Birds中的一个被忽略:

class Birds: virtual public Animal {
public:
    Birds(const char* color,
          int childs,
          float avgLifetime,
          float incubation) :
         Animal(color, childs, avgLifetime) // Not called for Flamingo
   {}
   //Do something
};