I have a C++ program with 4 classes : Person, Student, Employee, and PartTimeStudent.
Student and Employee each derive from Person, and PartTimeStudent derives from all 3 classes (making it the most derived class). Person, Student, and Employee also have a derived function called VDescribe().
Please see the code below :
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
{
...
};
Note : In the code snippet above I have omitted the Constructors, Destructors and member variables because they are not relevant to the problem at hand.
When I try to compile the code, I get the following errors :
override of virtual function "Person::VDescribe" is ambiguous
'PartTimeStudent': ambiguous inheritance of 'void Person::VDescrive(void)'
'PartTimeStudent': ambiguous inheritance of 'void Person::VDescribe(void)'
However, this only occurs if both Student and Employee implement VDescribe(). If one of the classes does not implement VDescribe(), compilation is successful. I still get warnings though, e.g. the following warnings occur if I omit VDescribe() from Employee :
'PartTimeStudent': inherits 'Student::Student::VDescribe' via dominance
May I ask why this occurs? I would like to know why PartTimeStudent is unable to compile if all 3 classes implement VDescribe(), but if either Student or Employee does not have the function, PartTimeStudent is still compilable.
Imagine the scanario where Student
and Employee
implement VDescribe
, while PartTimeStudent
does not implement it. How would you expect this code to behave:
PartTimeStudent pts;
pts.VDescribe();
Which implementation of VDescribe
should be called? It's ambiguous, which is precisely why the compilation errors out.
When Employee
does not override VDescribe
, the situation is a bit different. PartTimeStudent
then has the following functions to inherit:
Person::VDescribe
overridden by Student::VDescribe
, coming via Student
Person::VDescribe
not overridden, coming via Employee
.Person::VDescribe
not overridden, coming via Person
.In this situation, Student::VDescribe
overrides Person::VDescribe
and is an unambiguous overrider, so the compiler is able to use it. However, it is warning you that there was an alternative inheritance path which did not go through this override. This warning is not very useful in practice, and is one of the few warning I routinely disable.
If you want your code to compile also in the case when both Student
and Employee
override VDescribe
, you actually have to override it in PartTimeStudent
too. The function will then have an unambiguous final overrider and the code will compile just fine. You can call one or both of the inherited implementations using qualified names. Example:
void PartTimeStudent::VDescribe()
{
Student::VDescribe();
if (isWorking()) Employe::VDescribe();
}