关于C++中多继承的问题?

ipk*_*iss 8 c++ inheritance multiple-inheritance diamond-problem

我有以下代码:

#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
#define MNAME 30
class Person {
public:
    char name[MNAME + 1];
};
class Student : public Person {
};
class Staff : public Person {
};
class Faculty : public Student, public Staff {
};

int _tmain(int argc, _TCHAR* argv[])
{
    Faculty faculty;
    cout << "Address of faculty.Person::name: " << &faculty.Person::name << endl;
    cout << "Address of faculty.Student::name: " << &faculty.Student::name << endl;
    cout << "Address of faculty.Staff::name: " << &faculty.Staff::name << endl;

    getch();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

执行时,程序会给出结果:

Address of faculty.Person::name: 0012FF20 // **Line 1**
Address of faculty.Student::name: 0012FF20 // **Line 2**
Address of faculty.Staff::name: 0012FF3F // **Line 3**
Run Code Online (Sandbox Code Playgroud)

我不明白.为什么地址Line 1Line 2不同Line 3,而学生和工作人员都从Person继承姓名?

Dou*_* T. 13

当您以这种方式执行多重继承时,您将获得祖父母类的两个副本.这是经典的可怕钻石问题,你试着这样做:


        Person
       /       \
     Student  Staff
       \       /
        Faculty

但通过正常的继承,你实际得到这个:

    Person   Person
      |        |
     Student Staff
       \       /
        Faculty

所以在一个Faculty实例中真的有2个人,这意味着你会得到2个名字.

要在上面的第一个图中获取菱形,您需要使用虚拟继承.

class Staff : public virtual Person {
};
class Student : public virtual Person {
};
Run Code Online (Sandbox Code Playgroud)


Lou*_*nco 9

通过常规的多重继承,您可以获得共享基类的多个副本.如果需要一个副本,请使用虚拟继承.

维基百科中解释得很好

class Student : public virtual Person {
};
class Staff : public virtual Person {
};
Run Code Online (Sandbox Code Playgroud)

会得到你所期望的