C++ : Multiple inheritance with polymorphism

浪子不回头ぞ 提交于 2019-12-05 13:02:36

问题


(pardon the noob question in advance)

I have 4 classes:

class Person {};
class Student : public Person {};
class Employee : public Person {};
class StudentEmployee : public Student, public Employee {};

Essentially Person is the base class, which are directly subclassed by both Student and Employee. StudentEmployee employs multiple inheritance to subclass both Student and Employee.

Person pat = Person("Pat");
Student sam = Student("Sam");
Employee em = Employee("Emily");
StudentEmployee sen = StudentEmployee("Sienna");


Person ppl[3] = {pat, sam, em};
//compile time error: ambiguous base class
//Person ppl[4] = {pat, sam, em, sen}; 

When I use an array of Person, the base class, I can put Person and all of its subclasses inside this array. Except for StudentEmployee, given the reason ambiguous base class.

Given that StudentEmployee is guaranteed to have all the methods and attributes of Person, is StudentEmployee considered a subclass of Person?

  • If so, Why does the compiler not allow me to assign an object to a variable of the type of its superclass?
  • If not, why not; and what would be the proper way to accomplish this?

Cheers


EDIT: Preemptively, this question is NOT the same as either of the following:
polymorphism relates inheritance
Inheritance mucking up polymorphism in C++?


回答1:


StudentEmployee certainly is a subclass of Person. The problem is it is so twice: It indirectly inherits Person twice (once through Student and once through Employee) and that's why you get the "ambiguous base class" error. To make sure StudentEmployee only inherits Person once, you have to use virtual inheritance, like so:

class Person {};
class Student : public virtual Person {};
class Employee : public virtual Person {};
class StudentEmployee : public Student, public Employee {};

This will fix your error.

There is another big problem with your code, though, and it's called slicing.

When you do this:

Person ppl[3] = {pat, sam, em};

An array of three Person objects will be created but those objects will be copy constructed using the implicitly defined copy constructor of the Person class. Now, the problem with this is that the objects in your array will be just Person objects and not objects of the subclasses you want them to be.

To fix this, you'll have to make an array of pointers to Person objects, like this:

Person* ppl[] = {new Person("Pat"), new Student("Sam"),
                 new Employee("Emily"), new StudentEmployee("Sienna")};

or

Person* ppl[] = {&pat, &sam, &em, &sen};



回答2:


There are two equally possible paths from an object of type StudentEmployee to be a Person.

You need to use the keyword virtual for both Student and Employee classes. See FAQ 25.8 In fact go through that entire section.



来源:https://stackoverflow.com/questions/3541110/c-multiple-inheritance-with-polymorphism

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!