C++ 混合基类的虚拟继承和非虚拟继承
代码如下:C++ 混合基类的虚拟继承和非虚拟继承,c++,inheritance,constructor,multiple-inheritance,virtual-inheritance,C++,Inheritance,Constructor,Multiple Inheritance,Virtual Inheritance,代码如下: struct Biology { Biology() { cout << "Biology CTOR" << endl; } }; struct Human : Biology { Human() { cout << "Human CTOR" << endl; } }; struct Animal : virtual Biology { Animal() { cout << "An
struct Biology
{
Biology() { cout << "Biology CTOR" << endl; }
};
struct Human : Biology
{
Human() { cout << "Human CTOR" << endl; }
};
struct Animal : virtual Biology
{
Animal() { cout << "Animal CTOR" << endl; }
};
struct Centaur : Human, Animal
{
Centaur() { cout << "Centaur CTOR" << endl; }
};
int main()
{
Centaur c;
return 0;
}
为什么?
由于我们创建了一个Centaur
对象,我们从构建Centaur
开始,首先构建Human
,Animal
,最后构建Centaur
(我们从派生程度较低的到派生程度最高的)
让我们从人类开始:
人类
继承自生物学
,因此我们首先调用生物学
的构造函数。
既然构建了Human
的基类,我们就可以最终构建Human
本身了。
但是相反,生物学
又被构建了强>
为什么??幕后发生了什么
请注意,这完全是有意离开动物
实际上从生物学
继承,同时也是有意离开人类
非实际上从生物学
继承
我们用一种错误的方式解决了可怕的钻石问题:人类和动物实际上都应该继承生物学才能成功
我只是好奇
此外,请参见以下代码:
struct Biology
{
Biology() { cout << "Biology CTOR" << endl; }
};
struct Human : virtual Biology
{
Human() { cout << "Human CTOR" << endl; }
};
struct Animal : Biology
{
Animal() { cout << "Animal CTOR" << endl; }
};
struct Centaur : Human, Animal
{
Centaur() { cout << "Centaur CTOR" << endl; }
};
int main()
{
Centaur c;
return 0;
}
这是因为半人马最初继承了人类,然后继承了动物
如果顺序是相反的,我们将获得与之前相同的结果,在第一个示例中,两个生物学实例被构造成一行
这是什么逻辑
请试着解释你的方式,我已经检查了很多关于这个的网站。但是似乎没有一个能满足我的要求。从输出中可以清楚地看出,两个生物学
对象被实例化。这是因为您只创建了一个继承
虚拟
。两个基类实例是可怕的钻石问题中模棱两可的原因,解决方法是(如我们所知)继承生物学
虚拟
层次结构概述:
Biology Biology
| | # one and only one inheritance virtual
Human Animal
\ /
Centaur
好的,让我们再次阅读输出,记住以下规则:
- 基类在派生类之前构造
- 基类是按照它们在基说明符列表中出现的顺序构造的
- 虚拟基类是由最派生的类在非虚拟基类之前构造的
动物
虚拟
ly继承自生物学
:
Biology CTOR # virtual base class inherited from Animal
Biology CTOR # non-virtual base class of Human
Human CTOR # Human itself
Animal CTOR # Animal's virtual base class already constructed
Centaur CTOR
Biology CTOR # virtual base class inherited from Human
Human CTOR # Human's virtual base class already constructed
Biology CTOR # non-virtual base class of Animal
Animal CTOR # Animal itself
Centaur CTOR
第二个输出-人类
虚拟
ly继承自生物学
:
Biology CTOR # virtual base class inherited from Animal
Biology CTOR # non-virtual base class of Human
Human CTOR # Human itself
Animal CTOR # Animal's virtual base class already constructed
Centaur CTOR
Biology CTOR # virtual base class inherited from Human
Human CTOR # Human's virtual base class already constructed
Biology CTOR # non-virtual base class of Animal
Animal CTOR # Animal itself
Centaur CTOR
更多信息标准段落(
[class.base.init]/10
):
在非委托构造函数中,初始化在
顺序如下:
-首先,并且仅适用于大多数
派生类(1.8),虚拟基类按以下顺序初始化
它们出现在定向对象从左到右的深度优先遍历上
基类的非循环图,其中“从左到右”是
派生类中基类的外观
基本说明符列表
-然后,在中初始化直接基类
在基本说明符列表中显示的声明顺序
(无论mem初始值设定人的顺序如何)
非虚拟继承是一种排他性关系,就像成员关系一样。一个类可以是给定完整对象中另一个类的非虚拟基类 这意味着类可以重写非虚拟基类的虚拟函数,而不会导致冲突或问题 构造函数还可以可靠地初始化非虚基 只有虚基可以是完整对象的许多间接基的直接基类。因为虚拟基类可以共享,所以重写器可能会冲突 构造函数可以尝试初始化ctor init列表中的虚拟基子对象,但如果该类是进一步派生的,则该部分ctor init列表将被忽略
Biology
继承的所有基类在它们之间共享一个Biology
base实例Biology
非虚拟继承的基类都有Biology
的一个实例每个类别中都有一个基本类,因此有一个由人类引入的
生物学(原则上与其他人共享)和一个由动物引入的生物学(从未与任何其他基本类共享)。这个答案是金色的。谢谢;)多好的问题啊!谢谢你的回答,虽然一年后哈哈