派生 class 继承虚拟 class c++
Derived class that inherits virtual class c++
class vehicle{
...
};
class motorVehicle: virtual public vehicle{
...
};
class twoWheels: virtual public vehicle{
...
};
class motorcycle: public motorVehicle, public twoWheels, virtual vehicle{//(1)
....
};
(1) 为什么 class motorcycle 必须继承 class vehicle,而它已经包含在 classes motorVehicle 和 twoWheels 中?
在书中的解释中写道 class motorcycle 必须继承 class vehicle 以确保调用基础 class (vehicle)的构造函数。如果这个解释是正确的,我不明白为什么会说"virtual vehicle"?这是什么类型的继承?
这段代码
class motorcycle: public motorVehicle, public twoWheels, virtual vehicle{//(1)
....
};
从 motorVehicle
和 twoWheels
继承了您的 class,它们都已经继承了 vehicle
。因此,您必须消除 vehicle
的构造歧义,并将 virtual vehicle
添加到继承层次结构中,方法是选择由任何其他继承的 class.
调用的第一个可用构造函数
首先,给出的问题的解决方案,肯定是一个解决方案,但在我看来不是最好的。
这是为了解决所谓的diamond inheritance问题。为此,了解虚拟继承以及 public 和私有继承之间的区别很重要。
Public inheritance
表示派生的 class 也可以被视为并转换为继承的 class。在您的特定情况下,可以将 motor vehicle
转换为 vehicle
。如果继承是私人的。这是不可能的。
同样适用于 motorcycle
。可以考虑twoWheels
和motorVehicle
。但是由于这两者都可以被视为车辆,因此出现了问题。如果您想将 motorCycle
转换为 vehicle
怎么办?是否应该先转换为 twoWheels
,然后再转换为 vehicle
。或者它先到 motorVehicle
然后到 vehicle
。
不仅如此,在 vehicle 中声明的任何变量或函数也可以在 motorcycle
中调用。但是它应该调用 twoWheels
的那些然后调用 motorVehicle
.
所以本质上有两个 vehicles
正在构造,这会产生歧义。为了解决这个虚拟继承而引入。这允许您自己初始化 inheritance chain 中的任何 class。为此,没有必要自己从初始化的 class 继承。
这就是为什么我不同意提出的解决方案。像这样编写 motorcycle
构造函数就足够了:
motorcycle::motorcycle():
vehicle(),//n.b. this order is Not relevant, vehicle will be constructed first. No matter the order in this list.
twoWheels(),
motorVehicle()
{
}
class vehicle{
...
};
class motorVehicle: virtual public vehicle{
...
};
class twoWheels: virtual public vehicle{
...
};
class motorcycle: public motorVehicle, public twoWheels, virtual vehicle{//(1)
....
};
(1) 为什么 class motorcycle 必须继承 class vehicle,而它已经包含在 classes motorVehicle 和 twoWheels 中? 在书中的解释中写道 class motorcycle 必须继承 class vehicle 以确保调用基础 class (vehicle)的构造函数。如果这个解释是正确的,我不明白为什么会说"virtual vehicle"?这是什么类型的继承?
这段代码
class motorcycle: public motorVehicle, public twoWheels, virtual vehicle{//(1)
....
};
从 motorVehicle
和 twoWheels
继承了您的 class,它们都已经继承了 vehicle
。因此,您必须消除 vehicle
的构造歧义,并将 virtual vehicle
添加到继承层次结构中,方法是选择由任何其他继承的 class.
首先,给出的问题的解决方案,肯定是一个解决方案,但在我看来不是最好的。
这是为了解决所谓的diamond inheritance问题。为此,了解虚拟继承以及 public 和私有继承之间的区别很重要。
Public inheritance
表示派生的 class 也可以被视为并转换为继承的 class。在您的特定情况下,可以将 motor vehicle
转换为 vehicle
。如果继承是私人的。这是不可能的。
同样适用于 motorcycle
。可以考虑twoWheels
和motorVehicle
。但是由于这两者都可以被视为车辆,因此出现了问题。如果您想将 motorCycle
转换为 vehicle
怎么办?是否应该先转换为 twoWheels
,然后再转换为 vehicle
。或者它先到 motorVehicle
然后到 vehicle
。
不仅如此,在 vehicle 中声明的任何变量或函数也可以在 motorcycle
中调用。但是它应该调用 twoWheels
的那些然后调用 motorVehicle
.
所以本质上有两个 vehicles
正在构造,这会产生歧义。为了解决这个虚拟继承而引入。这允许您自己初始化 inheritance chain 中的任何 class。为此,没有必要自己从初始化的 class 继承。
这就是为什么我不同意提出的解决方案。像这样编写 motorcycle
构造函数就足够了:
motorcycle::motorcycle():
vehicle(),//n.b. this order is Not relevant, vehicle will be constructed first. No matter the order in this list.
twoWheels(),
motorVehicle()
{
}