摘自《C++程序設計》
如果一個派生類有多個直接基類,而這些直接基類又有一個共同的基類,則在最終的派生類中會保留該間接共同基類數據成員的多份同名成員。
C++提供虛基類(virtual base class)的方法,使得在繼承間接共同基類時只保留一份成員。
下面舉例說明:
在如下的圖中:
Person類是Student和Teacher的基類,而Graduate類又繼承自Student和Teacher類。
如果使用虛基類的話,Graduate將有兩份age拷貝,兩份gender拷貝,兩份name拷貝,一個來自Student,一個來自Teacher。即Student::age,Teacher::age,Student::gender,Teacher::gender,Student::name,Teacher::name,如果不使用虛基類,我們可以在Graduate以類名::類成員的形式對同名成員進行訪問。但是顯示,這我不是我們希望的,同樣的副本我們只需要一份。所以C++中提出了虛基類的實現方式。
聲明虛基類的一般形式是:
class 派生類名:virtual 繼承方式 基類名稱
下面是上面實例的代碼:
類聲明person.h:
#pragma once
#include
using namespace std;
class Person
{
protected:
string name;
char gender;
int age;
public:
Person(string name, char gender, int age);
};
class Teacher : virtual public Person
{
protected:
string title;
public:
Teacher(string name, char gender, int age, string title);
};
class Student: virtual public Person
{
protected:
double score;
public:
Student(string name, char gender, int age, double score);
};
class Graduate : public Teacher, public Student
{
private:
double wage;
public:
Graduate(string name, char gender, int age, double score, string title, double wage);
void show();
};
類實現person.cpp:
#include
#include "person.h"
Person::Person(string name, char gender, int age)
{
this->name = name;
this->gender = gender;
this->age = age;
}
Teacher::Teacher(string name, char gender, int age, string title) : Person(name, gender, age)
{
this->title = title;
}
Student::Student(string name, char gender, int age, double score) : Person(name, gender, age)
{
this->score = score;
}
Graduate::Graduate(string name, char gender, int age, double score, string title, double wage) : Person(name, gender, age), Teacher(name, gender, age, title), Student(name, gender, age, score)
{
this->wage = wage;
}
void Graduate::show()
{
cout << "name: " << name << '\n';
cout << "age: " << age << '\n';
cout << "gender: " << gender << '\n';
cout << "score: " << score << '\n';
cout << "title: " << title << '\n';
cout << "wage: " << wage << endl;
}
int main()
{
Graduate graduate("tanzhenyu", 'M', 25, 85, "manager", 10000);
graduate.show();
return 0;
}
運行結果: