(事先原谅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 事实上,通过整个部分。