0% found this document useful (0 votes)
9 views

Lecture 7 - Inheritance

Uploaded by

HuayiLI1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

Lecture 7 - Inheritance

Uploaded by

HuayiLI1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

Computer Aided Engineering

Lecture 7
Inheritance

Dr C.F. Kwong
[email protected]
Department of Electrical and Electronic Engineering
Faculty of Science and Engineering
Room: PMB 310
Topics
Inheritance
Class Access
Base Pointers
Constructors and Destructors Issues
Redefining Base Class Functions
Virtual Functions
What Is Inheritance?
Provides a way to create a new class from an existing
class
The new class is a specialized version of the existing
class
The "is a" Relationship
Inheritance establishes an "is a" relationship
between classes.
– A poodle is a dog
– A car is a vehicle
– A flower is a plant
– A football player is an athlete
Inheritance – Terminology and Notation

Base class (or parent) – inherited from


Derived class (or child) – inherits from the base class
Notation:
class Student // base class
{
. . .
};
class UnderGrad : public student
{ // derived class
. . .
};
Back to the ‘is a’ Relationship

An object of a derived class 'is a(n)' object of the


base class
Example:
– an UnderGrad is a Student
– a Mammal is an Animal
A derived object has all of the characteristics of the
base class
'is a’ relationship vs ‘has a’ relationship
Is a relationship
class B {
};
class A : public B {
};
Is a relationship
class B {
};
class A {
B b;
};
What Does a Child Have?
An object of the derived class has:
all members defined in child class
all members declared in parent class

An object of the derived class can use:


all public members defined in child class
all public members defined in parent class
Inheritance - Hierarchies of Objects
main () {

apple lunch;

lunch.cost=23; // apple has all the members of fruit


}

Apple is said to be a (publicly) derived class of the base class fruit.

Alternatively, we say that apple inherits (the properties) of fruit.

Fruit

Apple Strawberry
Inheritance - Hierarchies of Objects
Of course, although apple is a fruit, the reverse is not true. So apple might
have more member variables and functions than fruit.

class fruit {

public:

float cost;

void eat();
};

class apple:public fruit { // apple is declared to be a “sub-


category” of fruit

public: Fruit

float no_pips; // and has some apple-specific properties

void peel();
};
Apple Strawberry
Topics
Inheritance
Class Access
Base Pointers
Constructors and Destructors Issues
Redefining Base Class Functions
Virtual Functions
Class Access Specifiers

1) public – object of derived class can be treated


as object of base class (not vice-versa)
2) protected – more restrictive than public,
but allows derived classes to know details of
parents
3) private – prevents objects of derived class
from being treated as objects of base class.
Inheritance vs. Access
How inherited base class
members
Base class members appear in derived class
private: x private x is inaccessible
protected: y base class
private: y
public: z private: z

private: x protected x is inaccessible


protected: y base class protected: y
public: z protected: z

private: x public x is inaccessible


protected: y base class protected: y
public: z public: z
Topics
Inheritance
Class Access
Constructors and Destructors Issues
Redefining Base Class Functions
Virtual Functions
Constructors and Destructors in Base and
Derived Classes

Derived classes can have their own constructors and


destructors
When an object of a derived class is created, the base
class’s constructor is executed first, followed by the
derived class’s constructor
When an object of a derived class is destroyed, its
destructor is called first, then that of the base class
Constructors and Destructors in Base
and Derived Classes
Program 5-14 (Continued)
Passing Arguments to
Base Class Constructor

Allows selection between multiple base class


constructors
Specify arguments to base constructor on derived
constructor heading:
Square::Square(int side) :
Rectangle(side, side)
Can also be done with inline constructors
Must be done if base class has no default constructor
Passing Arguments to
Base Class Constructor

derived class constructor base class constructor

Square::Square(int side):Rectangle(side,side)

derived constructor base constructor


parameter parameters
Topics
Inheritance
Class Access
Base Pointers
Constructors and Destructors Issues
Redefining Base Class Functions
Virtual Functions
Redefining Base Class Functions
Redefining function: function in a derived class that
has the same name and parameter list as a function
in the base class

Typically used to replace a function in base class with


different actions in derived class
Not the same as overloading – with overloading,
parameter lists must be different

Objects of base class use base class version of


function; objects of derived class use derived class
version of function
Base Class

Note setScore function


Derived Class

Redefined setScore function


From Program 15-7
Problem with Redefining

Consider this situation:


– Class BaseClass defines functions x() and y(). x()
calls y().
– Class DerivedClass inherits from BaseClass and
redefines function y().
– An object D of class DerivedClass is created and
function x() is called.
– When x() is called, which y() is used, the one defined in
BaseClass or the the redefined one in
DerivedClass?
Topics
Inheritance
Class Access
Base Pointers
Constructors and Destructors Issues
Redefining Base Class Functions
Virtual Functions
Polymorphism and Virtual Member Functions

Virtual member function: function in base class that


expects to be redefined in derived class
Function defined with key word virtual:
virtual void Y() {...}
Supports dynamic binding: functions bound at run
time to function that they call
Without virtual member functions, C++ uses static
(compile time) binding
Consider this function (from Program 15-9)

Because the parameter in the displayGrade function is a


GradedActivity reference variable, it can reference any object that is
derived from GradedActivity.

A problem occurs in Program 15-10 however...


The getLetterGrade member function returned ‘C’ instead of ‘P’.

GradedActivity class’s getLetterGrade function was executed instead


of the PassFailActivity class’s version of the function.
Virtual Functions
Look at this code - it is legal but is it
class fruit { what we probably intend?

public:
In particular,
void eat();
}; my_lunch->eat();
class apple:public fruit;
calls exactly the same function,
class strawberry:public fruit;

main () { fruit::eat();

fruit* my_lunch; // A pointer to my lunch


irrespective of whether my_lunch
int luck=rand()%2; // randomly either 0 or 1 actually points to an apple or a
strawberry
if(luck==1) {

my_lunch=new apple;

} else {

my_lunch=new strawberry;
}

my_lunch->eat();
}
Virtual Functions
We know that apple and strawberry must somehow actually have their own
versions of eat() and what we want is that the compiler checks to see
what my_lunch actually points to when eat() is called at run time and to
find and call the most appropriate version of eat() for it.

This is actually really easy to do:

We just add the word virtual before the function eat() as follows and re-
declare the function in each derived class.
Virtual Functions
class fruit {

public:

virtual void eat(); // eat() will be “redefined” by “sub classes”;


};

class apple:public fruit{

public:

virtual void eat(); // apple provides its own version of eat(); if not redefined
here then fruit’s eat() is used as a default
};

class strawberry:public fruit{

public:

virtual void eat(); // strawberry provides its own version of eat(); if not
redefined here then fruit’s eat() is used as a default
};
Virtual Functions
The various versions of the virtual function are defined as usual

Note the virtual does not appear in the definition, only the declaration

void fruit::eat() {
class fruit {

// general fruit eating public:


}
virtual void eat();
void apple::eat() {
};

// apple specific eating class apple:public fruit{


}
public:
void strawberry::eat() {
virtual void eat();
// strawberry specific eating };
}
class strawberry:public fruit{

public:

virtual void eat();


};
Virtual Functions
class fruit {
So considering, ...
virtual void eat();
if(luck==1) { };

my_lunch=new apple; class apple:public fruit{


...
} else { virtual void eat();
};
my_lunch=new strawberry;
class strawberry:public fruit{
}
...
virtual void eat();
my_lunch->eat(); };

if luck==1, my_lunch actually points to an apple and the compiler first looks for apple::eat()
and if it exists it uses it.

However, if apple::eat() didn’t exist it goes up the hierarchy to fruit::eat and uses that instead.

Similarly if luck==0, my_lunch actually points to a strawberry and the compiler first looks for
strawberry::eat() and if it finds it, uses it etc.
Virtual Functions
Note that the re-declaration of void eat() in the derived classes must
be of the same return type and arguments as the declaration in
the base class - different arguments means different function as
we know!

If we think about it, we realise that the derived classes are inheriting
the
interface of the eat() function from the base class, not its
implementation

One final point is that the destructor of base classes must always be
declared virtual for reasons of predictability in the order in which
the different destructors are called.

Virtual functions are great for code expansion as well as building into
the program the generality of certain functions
Virtual Destructors
It's a good idea to make destructors virtual if the
class could ever become a base class.
Otherwise, the compiler will perform static binding
on the destructor if the class ever is derived from.
See Program 15-14 for an example
Multiple Inheritance

A derived class can have more than one base class


Each base class can have its own access specification
in derived class's definition:
class cube : public square,
public rectSolid;

class class
square rectSolid

class
cube
Multiple Inheritance
Arguments can be passed to both base classes'
constructors:
cube::cube(int side) : square(side),
rectSolid(side, side, side);
Base class constructors are called in order given in
class declaration, not in order used in class
constructor
Multiple Inheritance

Problem: what if base classes have member


variables/functions with the same name?
Solutions:
– Derived class redefines the multiply-defined function
– Derived class invokes member function in a particular base
class using scope resolution operator ::
Compiler errors occur if derived class uses base class
function without one of these solutions

You might also like