(事先原谅noob问题)
我有4节课:
class Person {};
class Student : public Person {};
class Employee : public Person {};
class StudentEmployee : public Student, public Employee {};
实质上 Person
是基类,由两者直接子类化 Student
和 Employee
。 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
。问题是它是如此 两次:它间接继承 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
类。看到 常见问题25.8 事实上,通过整个部分。