.NODE

tr() and Internationalization

Multiple Inheritance

Multiple inheritance is a form of inheritance in which a class inherits the structure and behavior of more than one base class.

Common uses of multiple inheritance:

  • For crossing the functionality of very different classes with little overlap, such as in Figure 23.1.

    Figure 23.1. QWidget's inheritance

  • For implementing a common "pure interface" (class with only pure virtual functions) in a variety of different ways.[2]

    [2] As we see in Section 23.3.2.

Multiple inheritance hierarchies are more complex and are harder to design, implement, and understand than single inheritance hierarchies. They can be used to solve some difficult design problems, but should not be used if a simpler approach (such as aggregation) is feasible. As with single inheritance, multiple inheritance defines a static relationship among classes. It cannot be changed at runtime.

23.3.1. Multiple Inheritance Syntax

The example in this section demonstrates multiple inheritance syntax and usage.

The two base classes shown in Figure 23.2, Rectangle and ScreenRegion, each have particular roles to play on the screen. One class is concerned with shape and location, while the other is concerned with color and visibility characteristics. A Window must be a Rectangle and a ScreenRegion. They are defined in Example 23.6.

Figure 23.2. Window and ScreenRegion

Example 23.6. src/multinheritance/window.h

#include "color.h"
#include "point.h"

class Rectangle {
 public:
 Rectangle( Const Point& ul, int length, int width);
 Rectangle( const Rectangle& r) ;
 void move (const Point &newpoint);
 private:
 Point m_UpperLeft;
 int m_Length, m_Width;
};

class ScreenRegion {
 public:
 ScreenRegion( Color c=White);
 ScreenRegion (const ScreenRegion& sr);
 virtual color Fill( Color newColor) ;
 void show();
 void hide();
 private:
 Color m_Color;
 // other members...
};

class Window: public Rectangle, public ScreenRegion {
 public:
 Window( const Point& ul, int len, int wid, Color c)
 : Rectangle(ul, len, wid), ScreenRegion(c) {} <-- 1

 Window( const Rectangle& rect, const ScreenRegion& sr)
 : Rectangle(rect), ScreenRegion(sr) {} <-- 2

 // Other useful member functions ...
};
 

(1)Use base class ctors.

(2)Use base class copy ctors.

There are some syntax items in the classHead of the derived class that deserve some attention.

  • An access specifier, e.g., public or protected, must appear before each base class name if the derivation is not private.

    • Default derivation is private.
    • It is possible to have a mixture of public, protected, and private derivations.
    • The comma (,) character separates the base classes.
    • The order of base class initialization is the order in which the base classes are listed in the classHead.

Client code to put a Window on the screen is shown in Example 23.7.

Example 23.7. src/multinheritance/window.cpp

#include "window.h"

int main() {
 Window w(Point(15,99), 50, 100, Color(22));
 w.show(); <-- 1
 w.move (Point(4,6)); <-- 2
 return 0;
}
 

(1)calls ScreenRegion::show();

(2)calls Rectangle::move();

Member Initialization

Default initialization or assignment proceeds member by member in the order that data members are declared in the class definition: First, base classes; then, derived class members.

23.3.2. Multiple Inheritance with Abstract Interfaces

One situation where it is appropriate to use multiple inheritance is when more than one abstract interface is needed. Figure 23.3 shows a class diagram based on the MP3 Data Model assignment in Section 25.1. FileTagger inherits the DataObject/QObject for its signals and slots, as well as for its property() and setProperty() functions. FileTagger also needs the Mp3Song interface that defines all of the fields for which an ID3 tag should have getters/setters. Similarly, Mp3File needs both the DataObject and the Mp3Song interfaces, even though it is not connected to a physical MP3 file.

Figure 23.3. MP3 data model

Multiple inheritance can help reduce dependencies for client code. For example, a client function can have an Mp3Song parameter without needing id3lib or Qt in order to exploit the Mp3Song interface. Mp3Song, with only pure virtual functions, enforces the interface on all derived classes. Separating the interface from different implementations makes plugin-frameworks possible.

In Figure 23.3, QObject is one of the base classes that is multiply inherited. One restriction Qt has is that QObject must only be inherited once by each class; further, the QObject-derived base must be listed first in the list of base classes. Breaking this rule will lead to strange errors from the code generated by moc, the MetaObject compiler.



Point of Departure

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
Similar book on Amazon

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