0% found this document useful (0 votes)
20 views2 pages

C++ Multiple Inheritance

The document discusses C++ multiple inheritance (MI), highlighting its advantages over single inheritance and Java's interfaces. It uses an asteroids example to illustrate how MI allows for the inclusion of properties from conflicting domains without forcing unwanted superclass inheritance. The document also covers practical aspects of MI implementation, including casting and the complexities involved in C++ object management.

Uploaded by

masanjaya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views2 pages

C++ Multiple Inheritance

The document discusses C++ multiple inheritance (MI), highlighting its advantages over single inheritance and Java's interfaces. It uses an asteroids example to illustrate how MI allows for the inclusion of properties from conflicting domains without forcing unwanted superclass inheritance. The document also covers practical aspects of MI implementation, including casting and the complexities involved in C++ object management.

Uploaded by

masanjaya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 2

CS108, Stanford Handout #26

Winter, 98-99 Nick Parlante


C++ Multiple Inheritance

Multiple Inheritance
An advanced C++ feature
Java does not have it -- Java has "interfaces" which solve 50% of the problem that Multiple
Inheritance solves. Interfaces, however, have the advantage of avoiding much of the
implementation complication of MI.

MI Concepts
Simple "single" inheritance works well if there is a single domain (e.g. drawing), and the
classes are arranged by their position in that domain.
What if there are multiple, conflicting domains?
With single inheritance, you are forced to bring in super classes you do not really want.
MI is complex, but it addresses this problem

Asteroids Example
There is the gravity domain:
Subject to gravity: Asteroid, bomb
No gravity: ship, bullet
There is also the "Explodable" domain -- which does not align with the gravity domain:
Explodable: bomb, bullet
Not explodable: asteroid, ship

Asteroids Solution
Have small rational tree of gravity/no-gravity: root..spaceship, bullet vs. bomb, asteroid
Have a separate "Mixin" class to bring in the "Explodable" property just where necessary
Use MI to bring in qualities which don't fit into the single inheritance logical structure
Point: Not everything can be well described in a single inheritance hierarchy
Point: In a single inheritance hierarchy, you inherit things where you don't want -- EG the
Explodable behavior would have to be added way up in Object.

Multiple Inheritance Asteroids


Object Explodable
-Draw -Explode()

Gravity NoGravity
-Fall() -Fly()

Asteroid Bomb Ship Bullet

Asteroids Code Features


.h: list multiple superclasses: "class Bomb: public Gravity, public Explodable {"
Constructors: default constructor is still called automatically, or you can use the : syntax to
chain up.
Destructors: still called automatically
ISA relationship still holds:
Bomb* or Bullet* -- can send themselves Explode() message
Object* or Ship* -- cannot -- CT err

Casting
Suppose we have..
Object* o;
Gravity *g;
Bomb* b;
Explodable* e;

1) Up is automatic
g=b; // ok, no cast required

2) Down is ok, if correct


As before, you can cast down so long as it is correct.
g=b; // move up a class
b=(Bomb*)g; // cast back down -- ok since the object really is a Bomb
Use dynamic_cast<Bomb*>() to check at runtime

3) Sideways -- NOT OK
g=b; // move up a class as before
e=(Explodable*)g; // Move sideways to the other superclass NO, NOT RELIABLE

4) If you need to go sideways, go down instead


g=b; // move up a class
b=(Bomb*)g; // move down (ok, by rule (2))
e=b; // NOW CAN MOVE UP, in fact no cast is required
Remember: just cast down to what it really is -- the other cases will follow automatically

5) Void*
If you ever cast into a void*, cast back out to the exact same thing.
Void* v = b;
<time passes>
b= (Bomb*)v; // cast back to what it was when you put it in

MI Implementation
Object slices -- really complicate the C++ implementation. Multiple base addresses within
one object
Explode *e = b; // arithmetic here to access the Explodable base addr within a bomb.

Conclusion
Pick a "main" single inheritance hierarchy (EG LPane/LView etc in PowerPlant)
Then add in occaisional Mixin classes where nenecessary
Complex, but worthwhile for some problems

You might also like