類結構:
Person
/ \
Student Teacher
\ /
Graduate
不使用虛繼承時,Graduate 會有兩份 Person 成員(Student::age、Teacher::age 等),訪問需加作用域區分,浪費內存且易出錯。
class Teacher : virtual public Person { ... };
class Student : virtual public Person { ... };
class Graduate : public Teacher, public Student { ... };
virtual 關鍵字放在繼承方式前。最遠派生類(Graduate)構造函數直接調用虛基類構造函數。
#include <iostream>
#include <string>
using namespace std;
class Person {
protected:
string name; char gender; int age;
public:
Person(string n, char g, int a) : name(n), gender(g), age(a) {}
};
class Teacher : virtual public Person {
protected:
string title;
public:
Teacher(string n, char g, int a, string t)
: Person(n,g,a), title(t) {}
};
class Student : virtual public Person {
protected:
double score;
public:
Student(string n, char g, int a, double s)
: Person(n,g,a), score(s) {}
};
class Graduate : public Teacher, public Student {
double wage;
public:
Graduate(string n, char g, int a, double sc, string t, double w)
: Person(n,g,a), Teacher(n,g,a,t), Student(n,g,a,sc), wage(w) {}
void show() {
cout << "name: " << name << "\n"
<< "age: " << age << "\n"
<< "gender: " << gender << "\n"
<< "score: " << score << "\n"
<< "title: " << title << "\n"
<< "wage: " << wage << endl;
}
};
int main() {
Graduate g("tanzhenyu", 'M', 25, 85, "manager", 10000);
g.show();
return 0;
}
name: tanzhenyu age: 25 gender: M score: 85 title: manager wage: 10000
僅一份 Person 數據成員,直接以成員名訪問無需作用域。
dynamic_cast