單繼承:一個子類只有一個父類時稱爲單繼承
多繼承:一個子類有兩個或者兩個以上時這個繼承關係爲多繼承
菱形繼承是多繼承的一種特殊情況
在繼承中子類會繼承父類的所有的成員,可以看出菱形繼承有數據冗餘和二義性的問題。Assistant中會有Person的兩份數據。
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
int _age;
};
class Student : public Person{
public:
int _stuid;
};
class Teacher : public Person{
public:
int _sid;
};
class Assistant :public Teacher, public Student{
public:
int sss;
};
void test(){
Assistant a;
cout << "Assistant:" << sizeof(a) << endl;
Student s;
cout << "Student:" << sizeof(s) << endl;
Teacher t;
cout << "Teacher:" << sizeof(t) << endl;
Person p;
cout << "Person:" << sizeof(p) << endl;
}
int main() {
test();
system("pause");
return 0;
}
可以從上面看出來我們的Assistant中的sizeof(Assistant)爲20,但是現在我們的Teacher和Student都爲8,這樣可以看出來Assistant繼承出兩個Person中的對象。
解決辦法:對於菱形繼承中解決辦法是使用虛繼承。繼承時使用virtual關鍵字,就可以保證我們的數據只有一份,不會產生數據的二義性。
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
int _age;
};
class Student :virtual public Person{
public:
int _stuid;
};
class Teacher : virtual public Person{
public:
int _sid;
};
class Assistant :public Teacher, public Student{
public:
int sss;
};
void test(){
Assistant a;
cout << "Assistant:" << sizeof(a) << endl;
Student s;
cout << "Student:" << sizeof(s) << endl;
Teacher t;
cout << "Teacher:" << sizeof(t) << endl;
Person p;
cout << "Person:" << sizeof(p) << endl;
}
int main() {
test();
system("pause");
return 0;
}
產生的結果是:
但是爲什麼使用虛繼承會導致我們的sizeof變大呢?這就跟虛擬繼承本質相關。
虛繼承的原理
虛擬繼承就是在虛擬繼承時生成一張虛基表,
使用vs進行調試
可以看出我們的Assistant是在虛繼承的上面,Teacher中多出了一個虛基表指針,這個指針指向的就是虛基表虛基表中存放的是偏移量,通過偏移量就可以找到Person。
這樣就可以知道爲什麼sizeof(Assistant)的大小是20了。這也是虛基表指針實現虛繼承的原理。