C 构造函数订单,而虚拟继承

C++ constructor order while virtual inheritance

本文关键字:虚拟 继承 构造函数      更新时间:2023-10-16
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是继承人Virtual Animal

我认为它将按顺序到达:

Animal->Birds->Flamingo  

为什么跳过动物构造函数?

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

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

隐式等同于:

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

,如果您已经明确编写了它,那么您将期望将代码添加到Flamingo上以调用Animal上的构造函数(或允许Flamingo隐式调用Animal的默认构造函数(。此外,FlamingoAnimal实例的初始化覆盖了Birds'。

因此,初始化仍然是 Animal→Birds→Flamingo,但是Animal初始化是Flamingo所做的,并且Birds'初始化被跳过,因为Animal已经初始化。

带有虚拟碱基,它是称为虚拟基础构造函数的最派生的类。

因此,在您的情况下:

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)
    {}
    // ...
};

鸟类中的那个被忽略:

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