摘自《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; }
运行结果:
