22.3.3.2.  virtual Base Classes

[ fromfile: multiple-inheritance.xml id: virtualbaseclasses ]

A base class may be declared virtual. A virtual base class shares its representation with all other classes that have the same virtual base class.

Adding the keyword virtual in the classHeads of Student and Teacher, and leaving all the other details of the class definitions the same, produces Example 22.9.

Example 22.9. src/multinheritance/people.h

#include "qdatetime.h"

class Person {
public:
    Person(QString name, QDate birthdate)
    QObject(name.ascii()),
    m_Birthdate(birthdate) {}

    Person(const Person& p) : QObject(p),
    m_Birthdate(p.m_Birthdate) {}

private:
    QDate m_Birthdate;
};

class Student : virtual public Person {       1
    // other class members
};

class Teacher : virtual public Person {       2
    // other class members
}


class GraduateTeachingFellow :
    public Student, public Teacher {          3
public:
    GraduateTeachingFellow(const Person& p,
                           const Student& s, const Teacher& t):
    Person(p), Students(s), Teacher(t) {}     4
}

1

Note keyword virtual here.

2

virtual inheritance.

3

virtual not needed here.

4

It is necessary to initialize all virtual base classes explicitly in multiply-derived classes, to resolve ambiguity about how they should be initialized.

<include src="src/multinheritance/people.h" href="src/multinheritance/people.h" id="virtpeopleh" mode="cpp"/>


After using virtual inheritance, an instance of GradTeachingFellow might look like Figure 22.6.

Figure 22.6.  GradTeachingFellow - virtual

GradTeachingFellow - virtual

Each instance of a class that virtually inherits from another has a pointer (or a variable offset) to its virtual base class subobject. The virtual base class pointer is invisible to the programmer, and in general, not necessary to change.

With multiple inheritance, each virtual base class pointer points to the same object, effectively enabling the base class object to be shared among all of the derived-class "parts".

For any class with a virtual base among its base classes, a member initialization entry for that virtual base must appear in the member initialization for that class. Otherwise, the virtual base gets default initialization.