虚拟继承时的C++构造函数顺序
C++ constructor order while 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 构造函数?
有了虚基,就是最派生的class调用虚基的构造函数
所以在你的情况下:
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
};
由于 Birds
使用 Animal
的虚拟继承,因此 Birds
的任何派生也使用 Animal
的虚拟继承。特别是:
class Flamingo : public Birds { /* ... */ };
隐式等同于:
class Flamingo : virtual Animal, public Birds { /* ... */ };
如果您明确地编写了它,那么您会期望将代码添加到 Flamingo
以调用 Animal
上的构造函数(或允许 Flamingo
隐式调用 Animal
的默认构造函数)。而且,Flamingo
's initialization of the Animal
instance overrides Birds
'.
所以,初始化仍然是Animal
→Birds
→Flamingo
,但是Animal
初始化是Flamingo
所做的,Birds
' 初始化被跳过,因为 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
}
};
当我尝试创建新的 Flamingo
时,我跳过了 Animal
构造函数。
我猜这是因为 Birds
继承人虚拟 Animal
.
我以为它会按顺序到达:
Animal->Birds->Flamingo
为什么要跳过 Animal 构造函数?
有了虚基,就是最派生的class调用虚基的构造函数
所以在你的情况下:
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
};
由于 Birds
使用 Animal
的虚拟继承,因此 Birds
的任何派生也使用 Animal
的虚拟继承。特别是:
class Flamingo : public Birds { /* ... */ };
隐式等同于:
class Flamingo : virtual Animal, public Birds { /* ... */ };
如果您明确地编写了它,那么您会期望将代码添加到 Flamingo
以调用 Animal
上的构造函数(或允许 Flamingo
隐式调用 Animal
的默认构造函数)。而且,Flamingo
's initialization of the Animal
instance overrides Birds
'.
所以,初始化仍然是Animal
→Birds
→Flamingo
,但是Animal
初始化是Flamingo
所做的,Birds
' 初始化被跳过,因为 Animal
已经初始化。