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

C++ C++;虚继承时的构造函数顺序,c++,inheritance,virtual-inheritance,C++,Inheritance,Virtual Inheritance,当我尝试创建新的Flamingo时,我跳过了Animal构造函数。 我猜这是因为鸟是他们的虚拟动物 我想它会按顺序到达: class Animal { public: Animal(const char * color, int childs, float avgLifetime) { //Do something } }; class Birds: virtual public Animal { public: Birds(const char * c

当我尝试创建新的
Flamingo
时,我跳过了
Animal
构造函数。
我猜这是因为鸟是他们的虚拟动物

我想它会按顺序到达:

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

为什么要跳过动物构造器

对于虚拟基,它是调用虚拟基构造函数的派生最多的类

因此,在你的情况下:

Animal->Birds->Flamingo  
忽略来自鸟类的信息:

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
Animal
使用虚拟继承,因此
Birds
的任何派生也对
Animal
使用虚拟继承。特别是:

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
};
隐式等同于:

class Flamingo : public Birds { /* ... */ };
如果您已经明确地编写了它,那么您会希望向
Flamingo
添加代码以调用
Animal
上的构造函数(或者允许
Flamingo
隐式调用
Animal
的默认构造函数)。此外,
Flamingo
Animal
实例的初始化覆盖了
Birds


因此,初始化仍然是
Animal
→<代码>鸟类→
Flamingo
,但是
Animal
初始化是
Flamingo
所做的任何事情,
Birds
初始化被跳过,因为
Animal
已经初始化了。

你能解释一下吗?我是cppIm的初学者,我不确定我是否理解。。。新Flamingo(参数…)的构造函数顺序是什么?动物->鸟类->Flamingo@motis10,顺序相同,即动物->鸟类->火烈鸟,但
Flamingo
ctor将调用基类
Animal
ctor,而不是
Birds
。如果您没有通过
Flamingo:Animal(params)
显式调用它,它将调用
Animal
的默认ctor。试试看。@SamerTufail很棒。但是我将如何明确地调用动物(params)?@motis10只需执行
Flamingo::Flamingo(params):鸟类(parms),动物(parms)
是的,这是因为虚拟继承。离题的问题:为什么这里需要虚拟继承?虚拟继承的主要目的是解决“钻石问题”,你认为动物分类学会出现这种问题吗?是的。有更多的课程,我有钻石问题。这就解决了问题。但是我遇到了这个问题……大多数时候,你面对的钻石问题是一个糟糕设计的标志。你可以考虑使用合成而不是继承。在你的例子中,同时有猫和狗的动物是不自然的。使用类来表示对象集可能是个坏主意。对适用于对象的函数集使用抽象类。
class Flamingo : virtual Animal, public Birds { /* ... */ };