Multiple Inheritance
- Consider a character type for a RPG.
- Note the examples here will be limited in functionality to maintain clarity.
- In this case, the base class, PersonT, will contain all of the data.
- This will be limited to name, current Hp and Max Hp.
- I would like to build an person class.
- This will be an abstract base class.
- It will have methods to
- Observe, and Modify hp statistics.
- Observe the name.
- Speak
- And a pure virtual method to fight.
- The UML
- There seem to be multiple ways to mark a class as abstract
- Place the title in italics.
- Place
<< abstract>>
in the title.
- Place
{abstract}
after the name.
- Virtual Methods are marked in italics.
- And you can add abstract before the method in a pure virtual function.
- This is discussed in my UML book, but no examples are given.
- And I can't find any examples in any of my other books.
- I think you could also put
{abstract}
after the name.
- Italics seems to be the winner with not notation for pure virtual methods.
-
- PlayerT.h
- PlayerT.cpp
- I would like to derive both fighter and wizard classes.
- For now, Ignore the commented out code in these classes.
- The fighter
- The fighter starts with 10hp max.
- They also have the title "Sir" appended to their name
- They only take 1/2 damage
- When they fight, they "Whomp" for d10 damage.
- Oh, they have a have a special method, Workout.
- FighterT.h
- FighterT.cpp
- The wizard
- Starts with 6hp max.
- Have the title "Zapper" appended to their name.
- No special considerations for damage.
- But when they fight, they "Zap" for d4+2
- When they speak, they have a phrase of 30 random characters with random spaces inserted.
- They have a special method, Study
- WizardT.h
- WizardT.cpp
-
- There should be nothing new here except for the UML.
- I added a peasant class as well.
- I would now like to add a BattleMage
- This class inherits from both the Fighter class and the Wizard Class.
-
- This is called Multiple Inheritance.
- It is a good thing
- You can gain attributes from both parent classes.
- It is a bad thing
- Real problems with ambiguity.
- Let's add the class and see the problem.
- The Battle Mage
- Overrides ChangeHP, It only takes 3/4 damage.
- Overrides the name, title: Battlecaster
- Overrides speak, it speaks like a wizard, but only 1/2 of the message.
- Overrides Fight, it acts as a fighter 1/2 of the time and a wizard 1/2 of the time.
- We can inherit from multiple classes
-
class BattleMageT: public FighterT, public WizardT {
- BattleMageT.h
- BattleMageT.cpp
- The problem is, the code will not compile
- First of all, we need to understand what is happening in our inheritance model.
- This is the "diamond" problem.
- The Wizard brings in a PlayerT
- The Fighter also brings in a PlayerT.
- C++ Solves this by brining in two PlayerT's
- And we are unable to determine which version of HP() to call
- Along with all of the other things we get from PlayerT.
- This can be overcome with Virtual Base Classes
class WizardT: public virtual PlayerT
- This forces the end objects to only have one instance of the base class.
- As long as it is specified as a virtual base class each time.
- The second problem is constructors.
- Stroustrup states "The constructor of the base class is called from the constructor of the most derived class."
- So I call the PlayerT constructor in the BattleMageT ctor-initializer.
- The other constructors are called as well, but they do NOT call the constructor for the PlayerT.
- Take a look at bad1.cpp and bad2.cpp
- There is apparently a debate in the programming community if multiple inheritance should be used.
- Some languages don't allow it.
- Meyers' Discussion on multiple inheritance
- It is very easy to have ambiguity in names.
- He states that you can do
id.ClassNameT::FunctionName()
- He says "from the viewpoint of correct behavior, public inheritance should always be virtual"
- But this causes the objects to be bigger
- And code to run slower.
- He is also unhappy that the most derived class is responsible for constructing the virtual bases (both direct and indirect)
- He suggests
- Don't use virtual base classes.
- If you must use them, don't put data in them.
- In the end, he says to use multiple inheritance if you need it but it will make your code more complex.
- Gregorie is sort of non-committal
- He says you should decide for yourself i multipl inheritance is good.