代码之家  ›  专栏  ›  技术社区  ›  bguiz

C++:多态性的多重继承

  •  12
  • bguiz  · 技术社区  · 15 年前

    (请事先原谅noob问题)

    我有4个班:

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

    基本上 Person 是基类,它由两个类直接子类化 Student Employee . StudentEmployee 使用多重继承将两者子类化 学生 员工 .

    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}; 
    

    当我使用 我可以说,是头等舱 以及它在这个数组中的所有子类。除了 学生员工 ,因为基类不明确。

    鉴于 学生员工 保证具有 学生员工 被认为是人的一个子类?

    • 如果是这样,为什么编译器不允许我将对象赋给超类类型的变量?
    • 如果没有,为什么不呢?什么才是实现这一目标的正确方法呢?

    干杯


    编辑:先发制人,此问题与以下任一问题不同:
    polymorphism relates inheritance
    Inheritance mucking up polymorphism in C++?

    2 回复  |  直到 15 年前
        1
  •  13
  •   Community Mohan Dere    8 年前

    StudentEmployee 当然是 Person . 问题是这样的 两次 :它间接继承 两次(一次通过 Student 一次通过 Employee )这就是为什么会出现“模棱两可的基类”错误的原因。确定 学生员工 只继承 一次,你必须使用 虚拟继承 ,像这样:

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

    这将修复您的错误。

    不过,您的代码还有一个大问题,它被称为 slicing .

    当你这样做的时候:

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

    三个数组 将创建对象,但这些对象将使用 班级。现在,问题在于数组中的对象 对象而不是您想要的子类的对象。

    要解决这个问题,您必须对 对象,如:

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

    Person* ppl[] = {&pat, &sam, &em, &sen};
    
        2
  •  3
  •   dirkgently    15 年前

    类型的对象有两条同样可能的路径 StudentEmployee 成为一个 Person .

    你需要使用关键字 virtual 对于两者 Student Employee 类。见 FAQ 25.8 事实上,请仔细阅读整个部分。