这是代码:
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;
}
此代码打印:
Biology CTOR
Biology CTOR
Human CTOR
Animal CTOR
Centaur CTOR
为什么?
由于我们创建了一个Centaur
对象,我们从构建Centaur
,Human
和最后Animal
开始构建Centaur
(我们从少开始派生到最派生的。)
让我们从Human
开始:
Human
继承自Biology
,因此我们首先调用Biology
的构造函数。
现在构造了Human
的基类,我们最终可以构造Human
本身。
但相反, Biology
会再次构建!
为什么呢?幕后发生了什么?
请注意,完全故意让Animal
从Biology
继承,并且同时故意将Human
非虚拟地继承自Biology
}。
我们正在以错误的方式解决 Dreaded Diamond :人类和动物应该实际上继承Biology 以使其发挥作用。
我只是好奇。
另外,请参阅此代码:
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;
}
我们Human
实际上从Biology
继承,而Animal
设置为以“经典方式”继承。
但这一次,输出是不同的:
Biology CTOR
Human CTOR
Biology CTOR
Animal CTOR
Centaur CTOR
这是因为Centaur
首先从Human
继承 ,然后从Animal
继承然后。
如果顺序是反向的,那么在第一个例子中,我们已经获得了与之前相同的结果 - 连续构造了两个Biology
个实例。
这是什么逻辑?
请尝试解释一下你的方式,我已经检查过很多关于此事的网站。但似乎没有一个能满足我的要求。
答案 0 :(得分:38)
从输出中可以清楚地看到两个func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
print("inside didConnectPeripheral ...")
print("Data : \(peripheral.identifier) : \(peripheral.description)")
peripheral.delegate = self
let customService:CBUUID = CBUUID(string: Constants.UUID.CustomServcices)
peripheral.discoverServices([customService])
}
对象被实例化。这是因为您已经只有一个继承Biology
。两个基类实例是可怕钻石问题模棱两可的原因,解决方案是(我们知道) virtual
Biology
的继承。
回顾层次结构:
virtual
好的,让我们再次考虑这些规则来阅读输出:
第一个输出 - Biology Biology
| | # one and only one inheritance virtual
Human Animal
\ /
Centaur
Animal
继承自virtual
:
Biology
第二个输出 - 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
Human
继承自virtual
:
Biology
更具信息性的标准段落(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
):
在非委托构造函数中,初始化继续进行 以下顺序:
- 首先,仅适用于最多的构造函数 派生类(1.8),虚拟基类按顺序初始化 它们出现在深度优先的从左到右的遍历中 基类的非循环图,其中“从左到右”是基数的顺序 派生类中基类的外观 基符列表
- 然后,在中初始化直接基类 声明顺序显示在 base-specifier-list 中 (无论 mem-initializers 的顺序如何)。
...
答案 1 :(得分:2)
非虚拟继承是一种排他性关系,就像成员身份一样。类可以是给定完整对象中另一个类的非虚基类。
这意味着类可以覆盖非虚拟基类的虚函数,而不会引起冲突或问题。
构造函数也可以可靠地初始化非虚拟基础。
只有虚拟基础可以是完整对象的许多间接基础的直接基类。由于可以共享虚拟基类,因此覆盖可能会发生冲突。
构造函数可以尝试在ctor-init-list中初始化虚拟基础子对象,但如果进一步派生该类,则将忽略ctor-init-list的那部分。
答案 2 :(得分:1)
Biology
虚拟继承的所有基类在它们之间共享一个Biology
基础实例。Biology
继承非虚拟的所有基类都有Biology
的每个实例。每个类别中都有一个基础,因此Biology
引入Human
的一个实例(原则上与其他人共享)和Animal
引入的一个实例(从未与任何其他基类共享。)