inheritance constructors and inheritance function over-riding (redefinition) the stringstream class...

54
INHERITANCE

Upload: hester-quinn

Post on 18-Jan-2016

230 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

INHERITANCE

Page 2: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

TOPICS

InheritanceConstructors and InheritanceFunction Over-riding (Redefinition)The Stringstream classShadowing VariablesDestructors and InheritancePointers and InheritanceUpcasting and DowncastingMultiple Inheritance

Page 3: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

OBJECTIVES

After completing this topic, students should be able to:

Correctly design and use classes that use public inheritancein a C++ program* Know how to correctly call the parent constructor* know how to over-ride functions in the parent classWrite functions that generate a string representation of aclass, using the stringstream classDescribe the differences between upcasting and downcastingand know when to safely use eachCorrectly use multiple inheritance in a program

Page 4: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Inheritance is the act of deriving a new classfrom an already existing class. It is analogous to creating a new house blueprint from anexisting one.

Inheritance is useful when we find a naturalhierarchical relationship between classes.

Inheritance makes it possible to re-use existingcode, thus saving time and minimizing bugs.

Page 5: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

EXAMPLE AND TERMINOLOGY

Page 6: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Suppose that we are creating a newrole playing game, and we want tohave the following creatures:

dwarves elves fairies

Page 7: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

All of these are “creatures “. They all have • A name

• A strength value• A hitpoint value

dwarves elves fairies

Page 8: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

We could define a class for each such as:

class Dwarf{ private: string name; int strength; int hitpoints; … other … public: Dwarf( ); getDamage( ); . . .};

class Elf{ private: string name; int strength; int hitpoints; … other … public: Elf( ); getDamage( ); . . .};

class Fairy{ private: string name; int strength; int hitpoints; … other … public: Fairy( ); getDamage( ); . . .};

Page 9: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Note that all of these classes have some things in common

class Dwarf{ private: string name; int strength; int hitpoints; … other … public: Dwarf( ); getDamage( ); . . .};

class Elf{ private: string name; int strength; int hitpoints; … other … public: Elf( ); getDamage( ); . . .};

class Fairy{ private: string name; int strength; int hitpoints; … other … public: Fairy( ); getDamage( ); . . .};

Page 10: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

And they have some things that are different

class Dwarf{ private: string name; int strength; int hitpoints; … other … public: Dwarf( ); getDamage( ); . . .};

class Elf{ private: string name; int strength; int hitpoints; … other … public: Elf( ); getDamage( ); . . .};

class Fairy{ private: string name; int strength; int hitpoints; … other … public: Fairy( ); getDamage( ); . . .};

Page 11: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

We gain a lot of productivity and functionality if we factor the common

elements out into a base class.

Creaturenamestrengthhitpoints

dwarf elf fairy

Base class

Derived Class

Sometimes also called• parent class• super class

Sometimes also called• child class• sub class

This relationship is calledInheritance.

Page 12: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

If elves and fairies are both magicalcreatures, we might envision another

layer of base and derived class

Creaturenamestrengthhitpoints

dwarf

Base class

Derived ClassMagicalCreature

spells

elf fairy

Derived Class

Page 13: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

This is known as a class hierarchy

Creaturenamestrengthhitpoints

dwarf

MagicalCreature

spells

elf fairy

Dwarf and Magical CreatureInherit from Creature

Elf and Fairy InheritFrom Magical Creature

Page 14: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

This is known as a class hierarchy

Creaturenamestrengthhitpoints

dwarf

MagicalCreature

spells

elf fairy

Common things are definedin base classes

Unique things are definedin derived classes

Page 15: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

the protected modifier (#) tells usthat the variable name is accessiblefrom within the Creature class andfrom within any derived classes. That is,functions of the derived class can see theprotected data members defined in the base class.

Creaturenamestrengthhitpoints

Let’s look at the base class definition

Class Creature{ protected: string name; int strength; int hitpoints; public: Creature( ); int getDamage( ); . . .};

Page 16: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Creaturenamestrengthhitpoints

And the MagicalCreature class

Class MagicalCreature : public Creature{ protected: int spells; public: MagicalCreature( ); . . .};

The keyword public means that this class will inherit publicly from theCreature class. That is, a MagicalCreatureobject will have everything that a Creatureobject has, and everything declared as publicin the base class will be public in the derived class.

MagicalCreature

spells

Page 17: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

So . . . If I create a MagicalCreatureobject named Zor, then Zor has the following properties:• A name• strength• hitpoints

• spells - This comes from the MagicalCreature class

These come from the Creature class

Page 18: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

This kind of inheritance is known asan is-a relationship. That is, a MagicalCreature is a Creature.

An object of the MagicalCreature class can be used anyplace that an object of the Creature class can be used.

Page 19: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Let’s look at how we deal with differences between classes by Looking at the

getDamage( ) function..

dwarf elf fairy

getDamage( ) computes and returns the damage thatthis creature inflicts in one round of combat.

Every creature inflicts damage that is a random numberbetween 1 and the creature’s strength value.

Page 20: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Dwarves are good fighters, andhave a 25% chance ofinflicting an additional

50 damage points

Magical creatures can double thedamage points if they have a magic spell.

Fairies are very quick, sothey get to attack twice.

Page 21: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Creaturenamestrengthhitpoints

Since the damage that any creature can inflictis defined as a random number between 0 and the creature’s strength value, we could writethe following code in the base class:

int Creature::getDamage( ){ int damage = (rand( ) % strength) + 1; return damage;}

Page 22: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Creaturenamestrengthhitpoints

Dwarves have a 25% chance of inflicting an additional 50 damage points. So thegetDamage( ) function in the Dwarf class might look like:

int Dwarf::getDamage( ){ int damage = (rand( ) % strength) + 1; if (rand( ) % 100 < 25) damage = damage + 50; return damage;}

dwarf

Page 23: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Creaturenamestrengthhitpoints

int Dwarf::getDamage( ){ int damage = (rand( ) % strength) + 1; if (rand( ) % 100 < 25) damage = damage + 50; return damage;}

dwarf

int Creature::getDamage( ){ int damage = (rand( ) % strength) + 1; return damage;}

Notice that both the Creature class and the Dwarf classhave a function named getDamage( );

This is called Function Over-riding.

Page 24: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

We over-ride, a member function in the base class by writing a similar function in the derivedclass that has exactly the same signature, but with a different implementation.

Function Over-riding

This is also called function re-definition.

Page 25: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

dwarf01

So, if I create a Dwarf object nameddwarf01, and send dwarf01 a getDamage( )message . . .

dwarf01.getDamage( )

The getDamage( ) function in the Dwarf class over-ridesthe getDamage( ) function in the base class, and so thegetDamage( ) function in the Dwarf class gets executed.

Page 26: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Note that if we had not re-defined the getDamage( )function in the Dwarf class, then it would have beenthe getDamage( ) function from the base class thatwould have been executed. This is because a Dwarfis-a creature.

Page 27: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

dwarf

Let’s let dwarves have a unique propertyof size. The class definition then might be:

Class Dwarf : public Creature{ private: int size; public: Dwarf( ); Dwarf(string, int, int, int); int getDamage( ); . . .};

Page 28: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

NOW CREATE A DWARF OBJECT …

Dwarf dwarf01 ( “Rohan”, 350, 500, 25);

dwarf01

name

strength

hitPoints

When the constructor is called, thecomputer looks at the Dwarf classto see how much storage to allocate.It notes that a Dwarf is a Creature,so it looks at the Creature class also.Enough storage is allocated for thedata members of both the base and the derived classes. size

Creature Part

Dwarf Part

Page 29: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Dwarf::Dwarf (string _nme, int _strngth, int _hpts, int _sze) : Creature (_nme, _strngth, _hpts){ size = _sze;}

The Dwarf Constructor

Constructors are not inherited. Inorder to initialize the parent class wemust invoke the base class constructor.This is done with an initializer list.

If you do not explicitly call the Creatureconstructor, the default Creature constructoris called automatically

Page 30: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

SHADOWING VARIABLES

If a child class declares a variable using the same nameas a variable in a parent class, the variable in the child class is said to shadow the variable in the parent.

Shadowing variables is not usually recommended.

Page 31: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

The Stringstream class

Page 32: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

The stringstream classes support reading from or writingto a buffer in memory, just as if we were reading from orwriting to a stream.

#include <iostream>#include <sstream>using namespace std;

int main( ){ float number = 3.21467; ostringstream s, t; s << "Hello World!"; t << "\nGoodbye Cruel World!"; t << “\nnumber = “ << number; cout << s.str( ) + t.str( ); system(“PAUSE”); return 0;}

ostringstream acts justlike an output stream class.

Page 33: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

The stringstream classes support reading from or writingto a buffer in memory, just as if we were reading from orwriting to a stream.

#include <iostream>#include <sstream>using namespace std;

int main( ){ float number = 3.21467; ostringstream s, t; s << "Hello World!"; t << "\nGoodbye Cruel World!"; t << “\nnumber = “ << number; cout << s.str( ) + t.str( ); system(“PAUSE”); return 0;}

Use stream insertionjust like with any otheroutput stream object

Page 34: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

The stringstream classes support reading from or writingto a buffer in memory, just as if we were reading from orwriting to a stream.

#include <iostream>#include <sstream>using namespace std;

int main( ){ ostringstream s, t; s << "Hello World!"; t << "\nGoodbye Cruel World!"; cout << s.str( ) + t.str( ); system(“PAUSE”); return 0;}

ostringstream has a memberfunction str( ) that returnsthe contents of the stream as a string.

Page 35: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Lets make it possible for each creature togenerate an output string describing itself.

My name is Rohan. My strength is 300 and myhitpoint value is 200. I am a dwarf and my size is 3.

My name is Elgier. My strength is 235 and myhitpoint value is 90. I am a magical creature andI have 3 spells. I am an Elf.

My name is Moondrops My strength is 190 and myhitpoint value is 75. I am a magical creature andI have 3 spells. I am a fairy and my speed is 16.

Page 36: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

The toString( ) function in the Base class:

string Creature::toString( ){ ostringstream creatureOut; creatureOut << “My name is “ << name << “.\n” << “My strength is “ << strength << “,\n” << “my hitpoint value is “ << hitPoints << “.”; return creatureOut.str( );}

Page 37: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

The toString( ) function in the MagicalCreature class:

string MagicalCreature::toString( ){ ostringstream magicalOut; magicalOut << “I am a Magical Creature, and I have ” << spells << “ spells.”;

return this->Creature::toString( ) + magicalOut.str( );}

Page 38: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

The toString( ) function in the Fairy class:

string Fairy::toString( ){ ostringstream fairyOut; fairyOut << “I am a fairy, and my speed is “ << speed << “.”;

return this->MagicalCreature::toString( ) + fairyOut.str( );}

Page 39: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

cout << bestFairy.toString( )

string Fairy::toString( ){ ostringstream fairyOut; fairyOut << “I am a fairy, and my speed is “ << speed << “.”; return this->MagicalCreature::toString( ) + fairyOut.str( );}

invokes

string MagicalCreature::toString( ){ ostringstream magicalOut; magicalOut << “I am a Magical Creature, and I have ” << spells << “ spells.”; return this->Creature::toString( ) + magicalOut.str( );}

invokes

invokes

string Creature::toString( ){ ostringstream creatureOut; creatureOut << “My name is “ << name << “.\n” << “My strength is “ << strength << “,\n” << “my hitpoint value is “ << hitPoints << “.”; return creatureOut.str( );}

Page 40: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

DESTRUCTORS

Destructors are not inherited. However, when adestructor in a derived class is invoked, it automatically invokes the destructor for thebase class.

Page 41: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

ORDER OF CONSTRUCTION AND DESTRUCTION

When an object of a derived class is created,the base class constructor is called first, thenthe derived class constructor is called.

Destruction occurs in the opposite order.The derived part is destroyed first, then thebase part is destroyed.

Page 42: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

PROTECTED INHERITANCE

A derived class can be defined using protected inheritance,as

class Circle : protected Shape { …

Protected inheritance means that public data in thebase class becomes protected in the derived classwhen it is inherited.

Page 43: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

PRIVATE INHERITANCE

A derived class can be defined using private inheritance,as

class Circle : private Shape { …

Private inheritance means that public data in thebase class becomes private in the derived classwhen it is inherited.

Page 44: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

VISIBILITY

In the case of public inheritance

Member functions in a derived class can access Public data and functions in the base class Protected data and functions in the base class

Functions outside of the derived class can access public data and functions in the base class public data and functions in the derived class

Page 45: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

INHERITANCE AND POINTERS

Because of the is-a relationship, an object of a publiclyderived class can always be treated as an object of thecorresponding base class.

In particular, you can always store the address of aderived class object in a base class pointer.

Page 46: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

Dwarf littleDwarf (“Egrew”, 600, 500, 2);

Creature *littleCreaturePtr;

littleCreaturePtr = &littleDwarf;

littleDwarf

littleCreaturePtr

littleDwarf isA Dwarf object.

littleCreaturePtr isa Creature pointer.

Page 47: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

If you now use the Creature pointer, it treatslittleDwarf as if it were an creature. For example …

littleDwarf

littleCreaturelPtr

cout << littleCreaturePtr -> toString( );

string Creature::toString( ){ ostringstream creatureOut; creatureOut << “My name is “ << name << “.\n” << “My strength is “ << strength << “,\n” << “my hitpoint value is “ << hitPoints << “.”; return creatureOut.str( );}

invokes

Page 48: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

This works because the derived class object is reallymade up of two parts, the base class part and thederived class part. The base class pointer thinks it is just pointing to the base class part.

littleDwarf

littleCreaturePtr

basepart

derivedpart

Page 49: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

You can store the address of a base class objectin a derived class pointer, but you must do anexplicit cast first!

Dwarf *littleDwarf;Creature anyOne (“joe”, 400, 190);

littleDwarf = static_cast<Dwarf*> (&anyOne);

Page 50: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

This is pretty dangerous and not often used, becausethe derived class pointer thinks it is pointing to aderived class object, but it really isn’t. This isreferred to as the “slicing problem”.

joe

littleDwarf

basepart

there is no derived part.If you try to access memberdata in the derived part, youwill get garbage!

Page 51: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

UPCASTING VS. DOWNCASTING

Casting from a descendant type to an ancestor type is known as upcasting. It is always safe, since you aremoving up the inheritance hierarchy. In our case, forexample, we are always know that a dwarf is an creature.

Casting from an ancestor type to a descendant typeis called downcasting. In our case, we can’t guaranteethat every creature is a dwarf, so downcasting a creature to a dwarf can be very dangerous, sincewe assume that information may be there that isn’t.

Page 52: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

MULTIPLE INHERITANCE

In C++, a derived class can have many parents,for example …

class MotorHome :public Vehicle, public House{ …

parents are separated by commas

Page 53: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

class MotorHome :public Vehicle, public House{ …

construction starts with the leftmostparent and proceeds to the right.

Vehicle is created firstThen HouseFinally MotorHome is created

Page 54: Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables Destructors and Inheritance Pointers

AMBIGUITY ERRORS

One of the major issues with multiple inheritanceis ambiguity. For example, suppose that the Houseclass and Vehicle class both have a function namedturnLightsOn. What happened in the following case:

MotorHome myRV;

myRV.turnLightsOn( );

the compiler gives you an ambiguity error.