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