Multiple Inheritance

Point of Departure

Multiple inheritance with QObject is discussed further in Qt Quarterly.[3]

[3] http://doc.trolltech.com/qq/qq15-academic.html#multipleinheritance

.3.3. Resolving Multiple Inheritance Conflicts

Figure 23.4 shows a UML diagram where multiple inheritance is being used incorrectly, for both interface and implementation. To make things even more complicated, we are inheriting from the same base class twice.

Figure 23.4. PersonStudentTeacher


Here, the class GradTeachingFellow is derived from two classes: Student and Teacher.

class GradTeachingFellow : public Student,
 public Teacher {
 // class member functions and data members
};


Name conflicts and design problems can arise from the improper use of multiple inheritance. In the above example, geTDepartment() function exists in both Student and Teacher. The student could be studying in one department and teaching in another, for example.

What happens when you call geTDepartment() on a GraduateTeachingFellow?


GraduateTeachingFellow gtf;
Person* pptr = >f;
Student * sptr = >f;;
Teacher* tptr = >f;
gtf.Teacher::getDepartment();
gtf.Student::getDepartment();
sptr->getDepartment()
tptr->getDepartment()
pptr->getDepartment(); // ambiguous - run-time error if virtual
gtf.getDepartment(); // Compiler error - ambiguous function call


The problem, of course, is that we have provided no getdepartment() function in the GradTeachingFellow class. When the compiler looks for a geTDepartment() function, Student and Teacher have equal priority.

Inheritance conflicts like these should be avoided because they lead to much design confusion later. However, in this case they can also be resolved with the aid of scope resolution.

.3.3.1. virtual Inheritance

In Figure 23.4, we inherited more than once from the same base class. There is another problem with that model: redundancy. When we create instances of this multiply inherited class, they might look like Figure 23.5.

Figure 23.5. GradTeachingFellownonvirtual


Person has attributes that we wish to inherit only once. It makes no sense for a GradTeachingFellow to have two birthdates and two names. virtual inheritance allows us to avoid the redundancy.

The strange problems that can arise when multiple inheritance is used in controversial ways, especially with the added complexities of virtual versus nonvirtual inheritance/functions, seem to have prompted the designers of Java to exclude multiple inheritance from their language. Instead, Java allows the programmer to define an interface, which consists only of abstract (pure virtual) functions. A Java class can then use the implements clause to implement as many interfaces as it needs.

.3.3.2. virtual Base Classes

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.

Add the keyword virtual in the classHead as shown in Example 23.8, leaving all the other details of the class definitions the same.

Example 23.8. 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.

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

Figure 23.6. GradTeachingFellowvirtual


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 allowing 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.



Review Questions

1.

What is a vtable?

2.

What is a polymorphic type?

3.

Which kinds of member functions are not inherited? Why?

4.

Under what circumstances should we have virtual destructors?

5.

What happens when a virtual function is called from a base-class constructor?

6.

What is virtual inheritance? What problems can it be used to solve?

7.

Why would one use non-public derivation?



Part I: Introduction to C++ and Qt 4

C++ Introduction

Classes

Introduction to Qt

Lists

Functions

Inheritance and Polymorphism

Part II: Higher-Level Programming

Libraries

Introduction to Design Patterns

QObject

Generics and Containers

Qt GUI Widgets

Concurrency

Validation and Regular Expressions

Parsing XML

Meta Objects, Properties, and Reflective Programming

More Design Patterns

Models and Views

Qt SQL Classes

Part III: C++ Language Reference

Types and Expressions

Scope and Storage Class

Statements and Control Structures

Memory Access

Chapter Summary

Inheritance in Detail

Miscellaneous Topics

Part IV: Programming Assignments

MP3 Jukebox Assignments

Part V: Appendices

MP3 Jukebox Assignments

Bibliography

MP3 Jukebox Assignments



An Introduction to Design Patterns in C++ with Qt 4
An Introduction to Design Patterns in C++ with Qt 4
ISBN: 0131879057
EAN: 2147483647
Year: 2004
Pages: 268

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net