我有一个带有4个类的C++程序:人员,学生,员工和PartTimeStudent。
Student和Employee分别从Person派生,而PartTimeStudent从所有3个类派生(使其成为派生最多的类)。人员,学生和雇员还具有称为VDescribe()的派生函数。
请参见下面的代码:
class Person
{
...
virtual void VDescribe();
...
};
class Student : virtual public Person
{
...
virtual void VDescribe();
...
};
class Employee : virtual public Person
{
...
virtual void VDescribe();
...
};
class PartTimeStudent : virtual public Person,
virtual public Student,
virtual public Employee
{
...
};
注意:在上面的代码片段中,我省略了构造函数,析构函数和成员变量,因为它们与当前问题无关。
当我尝试编译代码时,出现以下错误:
override of virtual function "Person::VDescribe" is ambiguous
'PartTimeStudent': ambiguous inheritance of 'void Person::VDescrive(void)'
'PartTimeStudent': ambiguous inheritance of 'void Person::VDescribe(void)'
但是,仅当Student和Employee都实现VDescribe()时,才会发生这种情况。如果其中一个类未实现VDescribe(),则编译成功。我仍然收到警告,例如如果我从Employee省略VDescribe(),则会发生以下警告:
'PartTimeStudent': inherits 'Student::Student::VDescribe' via dominance
请问为什么会这样?我想知道如果所有3个类都实现VDescribe(),为什么PartTimeStudent无法编译,但是如果Student或Employee没有函数,则PartTimeStudent仍可编译。
最佳答案
两个替代
想象一下scanario,其中Student
和Employee
实现VDescribe
,而PartTimeStudent
不实现它。您如何看待此代码的行为:
PartTimeStudent pts;
pts.VDescribe();
应该调用哪种
VDescribe
实现?这是模棱两可的,这正是编译出错的原因。一个替代
当
Employee
不覆盖VDescribe
时,情况有所不同。 PartTimeStudent
然后具有以下要继承的功能:Person::VDescribe
被Student::VDescribe
覆盖,通过Student
来Person::VDescribe
未覆盖,通过Employee
传入。 Person::VDescribe
未覆盖,通过Person
传入。 在这种情况下,
Student::VDescribe
会覆盖Person::VDescribe
,并且是明确的覆盖程序,因此编译器可以使用它。但是,警告您有一个替代继承路径没有通过此替代。该警告在实践中不是很有用,它是我经常禁用的少数警告之一。如果您还希望在
Student
和Employee
都覆盖VDescribe
的情况下也编译代码,则实际上您也必须在PartTimeStudent
中覆盖它。然后,该函数将具有明确的最终替代程序,并且代码将正常编译。您可以使用限定名称来调用一个或两个继承的实现。例:void PartTimeStudent::VDescribe()
{
Student::VDescribe();
if (isWorking()) Employe::VDescribe();
}