(заранее прошу прощения за вопрос новичка)
У меня есть 4 класса:
class Person {};
class Student : public Person {};
class Employee : public Person {};
class StudentEmployee : public Student, public Employee {};
Essentially Person
- это базовый класс, который непосредственно подклассы Студент
и Сотрудник
. StudentEmployee
использует множественное наследование для подкласса Student
и 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};
Когда я использую массив Person
, базовый класс, Я могу поместить Person
и все его подклассы в этот массив. За исключением StudentEmployee
, учитывая причину неоднозначного базового класса.
Учитывая, что StudentEmployee
гарантированно имеет все методы и атрибуты Person
, StudentEmployee
считается подклассом Person?
Приветствия
РЕДАКТИРОВАТЬ: Преимущественно, этот вопрос НЕ совпадает ни с одним из следующего:
полиморфизм относится к наследованию
Наследование наследует полиморфизм в C ++?
StudentEmployee
определенно является подклассом Person
. Проблема в том, что это так дважды : он косвенно наследует Person
дважды (один раз через Student
и один раз через Employee
), и поэтому вы получить ошибку "неоднозначный базовый класс". Чтобы убедиться, что StudentEmployee
наследует Person
только один раз, вы должны использовать виртуальное наследование , например:
class Person {};
class Student : public virtual Person {};
class Employee : public virtual Person {};
class StudentEmployee : public Student, public Employee {};
Это исправит вашу ошибку.
Однако есть еще одна большая проблема с вашим кодом, и она называется нарезкой .
Когда вы сделаете это:
Person ppl[3] = {pat, sam, em};
Будет создан массив из трех объектов Person
, но эти объекты будут скопированы с использованием неявно определенного конструктора копирования класса Person
. Теперь проблема в том, что объекты в вашем массиве будут просто объектами Person
, а не объектами подклассов, которые вы хотите, чтобы они были.
Чтобы исправить это, вам нужно создать массив указателей на объекты Person
, например:
Person* ppl[] = {new Person("Pat"), new Student("Sam"),
new Employee("Emily"), new StudentEmployee("Sienna")};
или
Person* ppl[] = {&pat, &sam, &em, &sen};
Есть два равновозможных пути от объекта типа StudentEmployee
до Person
.
Вам необходимо использовать ключевое слово virtual
для классов Student
и Employee
. См. FAQ 25.8 Фактически пройдите весь этот раздел.