aishy amer - encsstatic polymorphism: compile-time type and function checking dynamic polymorphism:...

97
COEN244: Polymorphism Aishy Amer Electrical & Computer Engineering Polymorphism means “variable behavior”/“ability to appear in many forms” Outline Casting between objects Using pointers to access objects Static polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-ridden at run time Pure Virtual functions: must be over-ridden Abstract Classes: classes with at least one pure virtual function Virtual destructor c A. Amer Polymorphism 1

Upload: others

Post on 06-Jul-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

COEN244: Polymorphism

Aishy Amer

Electrical & Computer Engineering

Polymorphism means “variable behavior”/“ability to appear in many forms”

OutlineCasting between objects

Using pointers to access objects

Static polymorphism: compile-time type andfunction checking

Dynamic polymorphism: run-time type andfunction checking

Virtual functions: can be over-ridden at run

time

Pure Virtual functions: must be over-ridden

Abstract Classes: classes with at least onepure virtual function

Virtual destructor

c© A. Amer Polymorphism 1

Page 2: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Casting

Casting: conversion from one data type to another typec o n v e r t t o t y p e ( express ion ) ;// Example :t = i n t ( x ) ; q=double ( y ) ;

c© A. Amer Polymorphism 2

Page 3: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Casting

Casting: conversion from one data type to another typec o n v e r t t o t y p e ( express ion ) ;// Example :t = i n t ( x ) ; q=double ( y ) ;

Standard numerical conversions are used forintegral promotions (e.g., enum to int)integral conversions (e.g., int to unsigned int)floating point conversions (e.g., float to double)floating-integral conversions (e.g., int to float)arithmetic conversions(e.g., converting operands to the type of the widestoperand before evaluation)

c© A. Amer Polymorphism 2

Page 4: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Casting

Implicit conversions:

Some conversions are performed automatically by thecompiler without intervention by the programmerStandard C++ conversions and user-defined conversionsare performed implicitly by the compiler where neededExamples?

Explicit conversions:

Conversions which must be explicitly specified by theprogrammer

c© A. Amer Polymorphism 3

Page 5: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

C++ explicit casting operators

static cast: convert one type to another type

can be used to reverse any of the implicit conversions(e.g., int to float)rely on static (compile-time) type informationfast and safe

c© A. Amer Polymorphism 4

Page 6: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

C++ explicit casting operators

static cast: convert one type to another type

can be used to reverse any of the implicit conversions(e.g., int to float)rely on static (compile-time) type informationfast and safe

dynamic cast: careful, type-sensitive casting at run time

for safe navigation of an inheritance hierarchy

reinterpret cast: type conversions on un-related types

produces something that has the same bit pattern as theoriginal

const cast : (UNSAFE!!)cast away the “const-ness” or “volatility” of a type

c© A. Amer Polymorphism 4

Page 7: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

C++ explicit casting operators

All casting operators have the same syntax:stat ic_cast conver t_ to_type ( expr ) ;/ / ==> Convert expr to type conver t_ to_typestat ic_cast <DerivedClass ∗> ( PointerToBaseObj )

Use the least dangerous (most specific) casting alternative

c© A. Amer Polymorphism 5

Page 8: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

C++ casting: examples

const i n t x =5;const i n t ∗ pX ; / / changeable p o i n t e r to constant i n t∗pX = 3; / / i l l e g a l − can ’ t use pX to modify an i n tpX = &someOtherIntVar ; / / l e g a l − pX can po in t somewhere e lse

i n t ∗ const pY ; / / constant p o i n t e r to changeable i n t∗pY = 4; / / l e g a l − can use pY to modify an i n tpY = &someOtherIntVar ; / / i l l e g a l − can ’ t make pY po in t anywhere e lse

const i n t ∗ const pZ ; / / const p o i n t e r to const i n t∗pZ = 5; / / i l l e g a l − can ’ t use pZ to modify an i n tpZ = &someOtherIntVar ; / / i l l e g a l − can ’ t make pZ po in t anywhere e lse

class Person {public :

/ / r e t u r n a const char∗ const ==> can ’ t change the p o i n t e r to po in t/ / somewhere else , and you can ’ t modify what the p o i n t e r po in t s toconst char∗ const GetName ( ) { return m_szName; } ;. . .c© A. Amer Polymorphism 6

Page 9: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

C++ casting: examples

i n t x = 37; i n t y = 8;

double q = x / y ; / / c l a s s i c mistake , r e s u l t i s rounded to an i n tcout << q ; / / p r i n t s " 4.000000"double q = ( double ) x / y ; / / cast r e s u l t as double so i t ’ s not roundedcout << q ; / / p r i n t s "4.625000"

/ / Bas cas t ing : fo rce the compi ler to put the address o f/ / a const i n t v a r i a b l e i n t o a normal i n t ∗const i n t x = 4; / / x i s const , i t can ’ t be modi f iedconst i n t ∗ pX = &x ; / / you can ’ t modify x through the pX p o i n t e rcout << x << endl ; / / p r i n t s "4 "

i n t ∗ pX2 = ( i n t ∗ )pX ; / / e x p l i c i t l y cast pX as an i n t ∗∗pX2 = 3; / / r e s u l t i s undef ined

cout << x << endl ; / / who knows what i t p r i n t s ?/ / The code compiles and runs w i thou t crashing , but who knows what i s x

c© A. Amer Polymorphism 7

Page 10: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

C++ casting: examples

/ / The Const_cast Operatorconst i n t x = 4; / / x i s const , i t can ’ t be modi f iedconst i n t ∗ pX = &x ; / / you can ’ t modify x through the pX p o i n t e r

cout << x << endl ; / / p r i n t s "4 "

i n t ∗ pX2 = const_cast < i n t ∗ > (pX ) ; / / e x p l i c i t l y cast pX as non−const

∗pX2 = 3; / / r e s u l t i s undef inedcout << x << endl ; / / who knows what i t p r i n t s ?

/ / With const_cast : change the const−ness of a va r iab le , and never i t s type

c© A. Amer Polymorphism 8

Page 11: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object casting

Object casting:

conversion of the type of an object to that of another type

s t a t i c c a s t <DerivedClass ∗> ( PointerToBaseObj )/ / Examplec i r c l e P t r = s t a t i c c a s t < C i r c l e ∗ >( p o i n t P t r ) ;

An object of a publicly derived class can also be treated asan object of its base class

c© A. Amer Polymorphism 9

Page 12: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object casting

Object casting:

conversion of the type of an object to that of another type

s t a t i c c a s t <DerivedClass ∗> ( PointerToBaseObj )/ / Examplec i r c l e P t r = s t a t i c c a s t < C i r c l e ∗ >( p o i n t P t r ) ;

An object of a publicly derived class can also be treated asan object of its base class

A base class object cannot automatically be treated as aderived class object!

We can use an explicit castto convert a base-class pointer to a derived-class pointer

Results of such conversion cannot be guaranteed ingeneral

c© A. Amer Polymorphism 9

Page 13: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object casting

Object casting is used forpointer conversion(e.g., derived class pointer to base class pointer)reference conversion(e.g., derived class reference to base class reference)pointer-to-member conversion(e.g., from pointer to member of a base class to pointer tomember of a derived class)

A conversion from type SS to TT can ONLY be done if

the conversion from type TT to SS is an implicit conversion

c© A. Amer Polymorphism 10

Page 14: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object pointer casting: static_cast

static_cast: no run-time type checking

Down-casting:convert a base class pointer to a derived class pointeronly if the conversion is unambiguous(& base class is non-polymorphic)

c© A. Amer Polymorphism 11

Page 15: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object pointer casting: static_cast

static_cast: no run-time type checking

Down-casting:convert a base class pointer to a derived class pointeronly if the conversion is unambiguous(& base class is non-polymorphic)

Example:c l a s s BankAcct { . . . } ;c l a s s SavingsAcct : public BankAcct { . . . } ;

/ / Given a b a s e c l a s s p o i n t e r ,/ / we can c a s t i t t o a d e r i v e d c l a s s p o i n t e r :void foo ( BankAcct∗ a c c t ) {SavingsAcct∗ d1 = s t a t i c c a s t <SavingsAcct∗> ( a c c t ) ;}

c© A. Amer Polymorphism 11

Page 16: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object pointer casting: static_cast

static cast : no run-time type checking→ if acct does not refer to an actual SavingsAcctthen the result of the cast is undefined

c© A. Amer Polymorphism 12

Page 17: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object pointer casting: static_cast

static cast : no run-time type checking→ if acct does not refer to an actual SavingsAcctthen the result of the cast is undefined

Applied to pointers to objects:Cast a pointer of a derived class to its base classCast a pointer of a base class to its derived class• The base class that is being casted is not checked to

determine whether this is a complete class of thedestination type or not:

c l a s s Base { . . . } ;c l a s s Derived : public Base { . . . } ;Base ∗ a = new Base ;Derived ∗ b = s t a t i c c a s t <Derived∗> ( a ) ;

c© A. Amer Polymorphism 12

Page 18: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast examples

Circle is derived from Point:class Poin t {

f r iend ostream& operator <<(ostream&, Po in t & ) ;public :

Po in t ( i n t = 0 , i n t = 0 ) ;void se tPo in t ( int , i n t ) ; / / access only base par t si n t getX ( ) const { return x } ;

protected :i n t x ; i n t y ;

} ;

/ / Const ruc torPoin t : : Po in t ( i n t a , i n t b ) { se tPo in t ( a , b ) ; }

c© A. Amer Polymorphism 13

Page 19: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast examples

const double PI = 3.14159;

class C i r c l e : public Poin t {f r iend ostream& operator <<(ostream&, C i r c l e &) ;public :

C i r c l e ( f l o a t = 0.0 , i n t = 0 , i n t = 0 ) ;void setRadius ( f l o a t ) ; / / access der i ve par t s on lyi n t getRadius ( ) const { return r ; }f l o a t area ( ) const { return PI∗ r ∗ r ; }protected :

f l o a t r ;} ;

C i r c l e : : C i r c l e ( f l o a t rad , i n t a , i n t b ) : Po in t ( a , b ) { setRadius ( rad ) ; }

c© A. Amer Polymorphism 14

Page 20: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast examples

/ / Normal UsePoin t p (4 , 5 ) , ∗ p o i n t P t r ;C i r c l e c (0 .707 , 1 , 2 ) , ∗ c i r c l e P t r ;

/ / Assign po in te r s normal lyp o i n t P t r = &p ;c i r c l e P t r = &c ;

cout << ∗ p o i n t P t r ; / / Ca l l operator << f o r Po in t/ / Output : ( x , y )= 4 5

cout << ∗ c i r c l e P t r ; / / Ca l l operator << f o r C i r c l e/ / Output : ( x , y , r )= 1 2 0.707

c© A. Amer Polymorphism 15

Page 21: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast examples

/ / Up−cas t ing : using C i r c l e ob jec t as a Po in t ob jec t

Poin t p (4 , 5 ) , ∗ p o i n t P t r ;C i r c l e c (0 .707 , 1 , 2 ) , ∗ c i r c l e P t r ;

/ / Assign C i r c l e ob jec t to Po in t ob jec t p o i n t e r/ / Can only access the Po in t i n f o !p o i n t P t r = &c ;

cout << ∗ p o i n t P t r ; / / Ca l l operator << f o r Po in t/ / Output : ( x , y )= 1 2

c© A. Amer Polymorphism 16

Page 22: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast examples

/ / Down−cas t ing : Po in t to C i r c l e

Poin t p (4 , 5 ) , ∗ p o i n t P t r ;C i r c l e c (0 .707 , 1 , 2 ) , ∗ c i r c l e P t r ;

/ / Assign C i r c l e ob jec t to Po in t ob jec t p o i n t e r/ / Can only access the Po in t i n f o !p o i n t P t r = &c ;

/ / Since p o i n t P t r r e a l l y po in t s to a C i rc le , we can/ / cast i t back to a C i r c l ec i r c l e P t r = stat ic_cast < C i r c l e ∗ >( p o i n t P t r ) ;cout << ∗ p o i n t P t r ; / / Ca l l operator << f o r Po in t/ / Output : ( x , y )= 1 2

cout << ∗ c i r c l e P t r ; / / Ca l l operator << f o r C i r c l e/ / Output : ( x , y , r )= 1 2 0.707

c© A. Amer Polymorphism 17

Page 23: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast examples

/ / Wrong / Unsafe use

Poin t p (4 , 5 ) , ∗ p o i n t P t r ;C i r c l e c (0 .707 , 1 , 2 ) , ∗ c i r c l e P t r ;

/ / Assign C i r c l e ob jec t to Po in t ob jec t p o i n t e r/ / Can only access the Po in t i n f o !p o i n t P t r = &p ;

/ / ! ! ! ! ! ! Can I do t h i s ?c i r c l e P t r = stat ic_cast < C i r c l e ∗ >( p o i n t P t r ) ;cout << ∗ p o i n t P t r ; / / Ca l l operator << f o r Po in t/ / Output : ( x , y )= 4 5

cout << ∗ c i r c l e P t r ; / / Ca l l operator << f o r C i r c l e/ / Output : ( x , y , r )= 4 5 ’ garbage ’

c© A. Amer Polymorphism 18

Page 24: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast summary

Point p(4, 5), *pointPtr;

..

..

.

..

.

.

Memory mapAddress

0x10000x10010x1002

120.707

c

45 p

0x30AA0x30A90x30A8

circlePtrpointPtr

0x30A80x1000

xx

r

xx

r

Circle c(0.707, 1, 2), *circlePtr;

p o i n t P t r = &p ; p o i n t P t r = &c ;c i r c l e P t r = s t a t i c c a s t <C i r c l e∗> ( p o i n t P t r ) ;

c© A. Amer Polymorphism 19

Page 25: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

static_cast summary

Point p(4, 5), *pointPtr;

..

..

.

..

.

.

Memory mapAddress

0x10000x10010x1002

120.707

c

45 p

0x30AA0x30A90x30A8

circlePtrpointPtr

0x30A80x1000

xx

r

xx

r

Circle c(0.707, 1, 2), *circlePtr;

p o i n t P t r = &p ; p o i n t P t r = &c ;c i r c l e P t r = s t a t i c c a s t <C i r c l e∗> ( p o i n t P t r ) ;

Safe casting: from a derived object to a base object

Be careful when casting from a base class to a derived classc© A. Amer Polymorphism 19

Page 26: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object pointer casting: Example

/ / L i s t i n g 15.1 Using po in te r s to access ob jec ts o f base and der ived classesclass Base { / / base c lass

protected : i n t x ;public :Base ( i n t a ) { x = a ; } / / to be used by Derivedvoid set ( i n t a ) { x = a ; } / / to be i n h e r i t e di n t show ( ) const { return x ; } / / to be i n h e r i t e d

} ;

class Derived : public Base { / / der ived c lassprivate : i n t y ;public :

Derived ( i n t a , i n t b ) : Base ( a ) , y ( b ){ } / / empty cons t ruc to r body

void access ( i n t &a , i n t &b ) const / / added i n der ived c lass{ a = Base : : x ; b = y ; }

} ;

c© A. Amer Polymorphism 20

Page 27: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object pointer casting: Example

i n t x , y ;Derived ∗pD = new Derived (50 ,80 ) ; / / unnamed der ived ob jec t

cout << " 1 . Derived po in te r , ob jec t , and der ived method \ n " ;pD−>access ( x , y ) ; / / no problem : type matchcout <<" x = " <<x <<" y = " <<y <<endl <<endl ; / / x=50 y=80

cout << " 2 . Derived po in te r , der ived ob jec t , base method \ n " ;cout << " x = " << pD−>show ( ) << endl << endl ; / / x = 50Base ∗pB = pD; / / p o i n t e r to same ob jec t

cout << " 3 . Base po in te r , der ived ob jec t , base method \ n " ;cout << " x = " << pB−>show ( ) << endl << endl ; / / x = 50/ / pB−>access ( x , y ) ; / / e r r o r : no access to der ived method

c© A. Amer Polymorphism 21

Page 28: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Object pointer casting: Example

cout << " 4 . Converted po in te r , der ived ob jec t and method \ n " ;( ( Derived ∗ ) pB)−>access ( x , y ) ; / / we know i t i s therecout <<" x = " <<x <<" y = " <<y <<endl <<endl ; / / x=50 y=80pB = new Base ( 6 0 ) ; / / unnamed base ob jec t

cout << " 5 . Base po in te r , base ob jec t , base method \ n " ;cout << " x = " << pB−>show ( ) << endl <<endl ; / / x = 60

cout << " 6 . Converted po in te r , base ob jec t , der ived method \ n " ;( ( Derived ∗ ) pB)−>access ( x , y ) ; / / pass on your own r i s kcout <<" x = " <<x <<" y = " <<y <<endl <<endl ; / / junk ! !

delete pD; delete pB ; / / necessary t i d i n e s s

c© A. Amer Polymorphism 22

Page 29: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Compile time versus Run time

Static type checking / function checkingAlso called compile-time checkingExamples?: d.show(); checked at compile time

Dynamic type checking / function checkingAlso called run-time checking, i.e., at execution timeExamples?: BasePtr->show();

c© A. Amer Polymorphism 23

Page 30: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism

An object is denoted by its name (identifier) and the typeassociated with this identifier

c© A. Amer Polymorphism 24

Page 31: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism

An object is denoted by its name (identifier) and the typeassociated with this identifier

Polymorphism (dynamic binding, virtual function):The principle that behavior of a function can varydepending on the actual type of an object

With polymorphism:Objects of different classes related by inheritance mayrespond differently to the same member function callThis allows a programmer to manipulate an object withoutknowing what kind of object it is

c© A. Amer Polymorphism 24

Page 32: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Types of polymorphism

Static polymorphism – (static binding or early binding):At compile time (at the earliest possible time):the compiler selects a method from several candidatesSelection is based on the type of the pointer to the object

c© A. Amer Polymorphism 25

Page 33: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Types of polymorphism

Static polymorphism – (static binding or early binding):At compile time (at the earliest possible time):the compiler selects a method from several candidatesSelection is based on the type of the pointer to the object

Dynamic polymorphism – (dynamic binding or late binding):At run time (at the latest possible time):the compiler selects a method from several candidatesBased on the type of the objectThis allows a programmer to manipulate an object withoutknowing what kind of object it is

c© A. Amer Polymorphism 25

Page 34: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Static polymorphism

Recall: In a derived class,you can redefine (this is?) functions of the base class⇒ compile-time solution

c© A. Amer Polymorphism 26

Page 35: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Static polymorphism

Recall: In a derived class,you can redefine (this is?) functions of the base class⇒ compile-time solution

Static polymorphism (early binding):When the compiler selects a method from severalpossible candidates at compile timeThe legality of the implementation(e.g., a member function invocation)is checked at compile timeExample: if Vehicle has a certain member function,Car also has that member function

c© A. Amer Polymorphism 26

Page 36: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic polymorphism

Dynamic polymorphism (late binding):When the compiler selects a method from severalpossible candidates at run timeThe legality of some types and functions is determinedbased on the dynamic type of the object at run time

Dynamic polymorphism is implemented through virtual functions

c© A. Amer Polymorphism 27

Page 37: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic polymorphism

Dynamic polymorphism (late binding):When the compiler selects a method from severalpossible candidates at run timeThe legality of some types and functions is determinedbased on the dynamic type of the object at run time

Also called "dynamic binding":the binding to the code that gets called is accomplisheddynamically (at run time)

Dynamic polymorphism is implemented through virtual functions

c© A. Amer Polymorphism 27

Page 38: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic polymorphism: When?

Suppose:

We have a base class "Shape" with various derived classes"Triangle", "Rectangle", etc.

Each derived class with its own print() member function

Collect objects of these derived classes into an array ofpointers to these objects CLASS ∗ arr[10]

c© A. Amer Polymorphism 28

Page 39: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic polymorphism: When?

Suppose:

We have a base class "Shape" with various derived classes"Triangle", "Rectangle", etc.

Each derived class with its own print() member function

Collect objects of these derived classes into an array ofpointers to these objects CLASS ∗ arr[10]

But what sort of pointers could we use?

Recall: A derived pointer can be assigned a base pointer⇒ Shape ∗ arr[10]: an array of pointers to the base class

Rectangle rec; arr[5] = &rec;:rec is the actual object; arr[5] is a pointer of type Shape

c© A. Amer Polymorphism 28

Page 40: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic polymorphism: When?

Assume we want to print the content of each object in thearray arr[i]->print()

Since the pointer points to a Shape object,the print() function of the Shape (base) class is calledNOT the appropriate derived class function!!

Solution? Dynamic binding (using virtual functions)

c© A. Amer Polymorphism 29

Page 41: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic polymorphism: When?

So: when you have a pointer to an object,this actual object may be of a derived class

A pointer to an object of type Vehicle*maybe actually be pointing to a Car objectA pointer to an object of type Shape*maybe actually be pointing to a Rectangle object

c© A. Amer Polymorphism 30

Page 42: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic polymorphism: When?

So: when you have a pointer to an object,this actual object may be of a derived class

A pointer to an object of type Vehicle*maybe actually be pointing to a Car objectA pointer to an object of type Shape*maybe actually be pointing to a Rectangle object

Dynamic binding implies that a base class pointer figures outwhich derived class it really points to at run-time

c© A. Amer Polymorphism 30

Page 43: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding

Create a group of related derived classes under a commonpublic base class

Equip each derived class with a function that performsprocessing specific to this derived class

Make sure that each function has the same name andsignature (interface)

Call this function through a base class pointer

c© A. Amer Polymorphism 31

Page 44: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding

Create a group of related derived classes under a commonpublic base class

Equip each derived class with a function that performsprocessing specific to this derived class

Make sure that each function has the same name andsignature (interface)

Call this function through a base class pointer

⇒ The called function does not depend on the type of the pointerthat points to the object

⇒ It depends on the type of the object pointed to by the pointer

c© A. Amer Polymorphism 31

Page 45: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding: Useful?

Before OOP: software reuse when new code call old code

Dynamic binding can improve reuse by letting old code callnew code

c© A. Amer Polymorphism 32

Page 46: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding: Useful?

Before OOP: software reuse when new code call old code

Dynamic binding can improve reuse by letting old code callnew code

Dynamic binding permits software extensibility:With OOP: a new code may be created, compiled, andtestedLater, this code can be called by a framework that waswritten long time agoThere is no need to change the old code:it does not even need to be recompiled

c© A. Amer Polymorphism 32

Page 47: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding: Useful?

Dynamic binding does not make static binding irrelevant

It introduces many additional dimension of complexity

c© A. Amer Polymorphism 33

Page 48: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding: Useful?

Dynamic binding does not make static binding irrelevant

It introduces many additional dimension of complexity

poly.method(...); OR poly->method(...);

Check if the target (here poly) is an object or a pointerIf it is an object:• Only static binding possible• Check the function signature and• Verify if the function call is correctIf the target is a pointer: consider dynamic binding

In most cases: the method being called depends on the typeof the pointer not on the type of the object

c© A. Amer Polymorphism 33

Page 49: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding: a scenario

If the target is a pointer: consider dynamic bindingDefine at which place in the inheritance hierarchy thepointer belongsIf the pointer is of the derived type:only static binding is possibleIf the pointer is of the base type:dynamic binding is possible

c© A. Amer Polymorphism 34

Page 50: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Dynamic binding: a scenario

If the pointer is of the base type: dynamic binding is possibleif the object the pointer points to is of the base type:no dynamic bindingif the object is of a derived type:dynamic binding is possible• If the function called

· is redefined in the appropriate derived class and· has the same name and signature as

the (virtual) function in the base class,

Apply dynamic binding implemented through virtual functions

c© A. Amer Polymorphism 35

Page 51: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Types of member functions

Defined in the base class and inherited in a derived classwithout redefinition

Defined in a derived class without a counterpart in the baseclass

c© A. Amer Polymorphism 36

Page 52: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Types of member functions

Defined in the base class and inherited in a derived classwithout redefinition

Defined in a derived class without a counterpart in the baseclass

Defined in the base class and redefined in a derived classwith the same name and same signature

Defined in the base class and redefined in a derived classwith the same name and different signature

Defined in the base class and redefined in a derived classwith the same name and same signature as virtualIn which case you can apply dynamic binding?

c© A. Amer Polymorphism 36

Page 53: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual functions

A virtual function is a member function of the base class thatcan be redefined at run-time

Even if the object is accessed by a base pointervirtual functions allow derived classesto replace the implementation of a function provided by thebase class at run time

c© A. Amer Polymorphism 37

Page 54: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual functions

A virtual function is a member function of the base class thatcan be redefined at run-time

Even if the object is accessed by a base pointervirtual functions allow derived classesto replace the implementation of a function provided by thebase class at run time

The replacement is always called whenever the object inquestion is of the derived class(even if the object is accessed by a base pointer)

This allows algorithms in the base class to be replaced in thederived class, even if users don’t know about the derivedclass

c© A. Amer Polymorphism 37

Page 55: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example: without virtual functions

class Shape {protected :i n t width , he igh t ;public :

void set ( i n t a , i n t b ) { width=a ; he igh t=b ; } / / access base pa r t on ly} ;

class Rectangle : public Shape {public :

i n t area ( void ) { return ( width ∗ he igh t ) ; } / / s p e c i f i c to Rect .} ;

class Tr iang le : public Shape {public :

i n t area ( void ) { return ( width ∗ he igh t / 2 ) ; } / / s p e c i f i c to T rg l .} ;

c© A. Amer Polymorphism 38

Page 56: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example: without virtual functions

Rectangle r e c t ;T r i ang le t r g l ;

Shape ∗ppoly1 = &r e c t ; / / two po in te r s to ob jec ts o f base c lass ShapeShape ∗ppoly2 = & t r g l ; / / They are assigned the addresses of/ / der ived classes r e c t and t r g l ( v a l i d ?)/ / ==> we can only r e f e r the members t h a t/ / Rectangle and Tr iang le i n h e r i t from Shape

ppoly1−>set ( 4 , 5 ) ; / / can use ppoly1 ;ppoly2−>set ( 4 , 5 ) ;

cout << r e c t . area ( ) << endl ; / / cannot use ppoly1 ; Output 20cout << t r g l . area ( ) << endl ; / / cannot use ppoly2 ; Output 10

c© A. Amer Polymorphism 39

Page 57: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example: without virtual functions

To make it possible for the pointers to the base class toaccess a member, we have to declared it in the base class

But what is the area of an undefined shape?

c© A. Amer Polymorphism 40

Page 58: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example: without virtual functions

To make it possible for the pointers to the base class toaccess a member, we have to declared it in the base class

But what is the area of an undefined shape?

To access a (virtual) member of a base class we must declareit as virtual so that the use of pointers to base objects can befully applied to derived objects

c© A. Amer Polymorphism 40

Page 59: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example: with virtual functions

class Shape {protected :i n t width , he igh t ;public :

void set ( i n t a , i n t b ) { width=a ; he igh t=b ; }/ / se t ( ) not v i r t u a l : i t does the same f o r a l l c lassesv i r t u a l i n t area ( void ) / / area ( ) as v i r t u a l f u n c t i o n/ / Does not make much sense here , but we need i t l a t e r{ return ( 0 ) ; } / / v i r t u a l : works s p e c i f i c i n der ived c l s .

} ;

class Rectangle : public Shape {public :

i n t area ( void ) { return ( width ∗ he igh t ) ; }} ;

c© A. Amer Polymorphism 41

Page 60: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example: with virtual functions

class Tr iang le : public Shape {public :

i n t area ( void ) { return ( width ∗ he igh t / 2 ) ; }} ;

/ / Test ingRectangle r e c t ;T r i ang le t r g l ;Shape poly ;Shape ∗ppoly1 = &r e c t ;Shape ∗ppoly2 = & t r g l ;Shape ∗ppoly3 = &poly ;

c© A. Amer Polymorphism 42

Page 61: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example: with virtual functions

ppoly1−>set ( 4 , 5 ) ;ppoly2−>set ( 4 , 5 ) ;ppoly3−>set ( 4 , 5 ) ;

/ / dynamic b ind ing :/ / At run−t ime the implementat ion o f the v i r t u a l f u n c t i o n/ / i s replaced by t h a t o f the der ived c lasscout << ppoly1−>area ( ) << endl ; / / ou tput : 20cout << ppoly2−>area ( ) << endl ; / / ou tput : 10cout << ppoly3−>area ( ) << endl ; / / ou tput : 0/ / desp i te v i r t u a l i t y we can dec lare an ob jec t o f type Shape/ / and to c a l l i t s area ( ) f u n c t i o n

c© A. Amer Polymorphism 43

Page 62: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual & non-virtual functions

Non-virtual member functions are resolved staticallyit is selected at compile-time based on the type of the pointerto the object

c© A. Amer Polymorphism 44

Page 63: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual & non-virtual functions

Non-virtual member functions are resolved staticallyit is selected at compile-time based on the type of the pointerto the object

Virtual member functions are resolved dynamicallyit is selected at run-time based on the type of the object (notthe type of the pointer to that object)

Dynamic binding creates extra space and time overhead but...

c© A. Amer Polymorphism 44

Page 64: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example without virtual functions

class Student {f r iend ostream& operator <<(ostream&, Student &) ;public :

Student ( char∗ pF , char∗ pL ) ;~Student ( ) ;

protected : char∗ f i r s t ; char∗ l a s t ;} ;

class COEN244 : public Student {public :COEN244( char∗ pF , char∗ pL ) ;~COEN244( ) { count−−; }void setGrade ( f loa t , f loa t , f loa t , f l o a t ) ;f l o a t grade ( ) ; / / <===s t a t i c i n t getCount ( ) { return count ; }

private :f l o a t assignment ; f l o a t quiz ; f l o a t midterm ; f l o a t f i n a l ;s t a t i c i n t count ;

} ;c© A. Amer Polymorphism 45

Page 65: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example without virtual functions

class ELEC311 : public Student {public :ELEC311( char∗ pF , char∗ pL ) ;~ELEC311 ( ) { count−−; }void setGrade ( f loa t , f loa t , f loa t , f l o a t ) ;f l o a t grade ( ) ; / / <===s t a t i c i n t getCount ( ) { return count ; }

private :f l o a t assignment ; f l o a t l a b o r a t o r y ; f l o a t midterm ; f l o a t f i n a l ;s t a t i c i n t count ;

} ;

c© A. Amer Polymorphism 46

Page 66: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example without virtual functions

class ELEC490 : public Student {public :ELEC490( char∗ pF , char∗ pL ) ;~ELEC490 ( ) { count−−; }void setGrade ( f l o a t ) ;f l o a t grade ( ) ; / / <===s t a t i c i n t getCount ( ) { return count ; }

private :f l o a t p r o j e c t ;s t a t i c i n t count ;

} ;

c© A. Amer Polymorphism 47

Page 67: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example without virtual functions

void p r i n t I n f o ( const Student ∗ ) ;

void main {COEN244 c1 ( " Jane " , "Doe" ) ;c1 . setGrade (50 , 55 , 25 , 95 ) ;p r i n t I n f o (&c1 ) ;

}

void p r i n t I n f o ( const Student∗ pStud ) {/ / Output name v ia stream i n s e r t i o n over loadcout << ∗pStud << endl ; / / QUESTION??? How do I know what k ind/ / o f Student pStud i s ?cout << pStud−>grade ( ) ; / / We cannot do t h i s ! ! !

}

c© A. Amer Polymorphism 48

Page 68: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example with virtual functions

class Student {f r iend ostream& operator <<(ostream&, Student &) ;public :

Student ( char∗ pF , char∗ pL ) ;~Student ( ) ;v i r t u a l f l o a t grade ( ) ; / / <===

protected : char∗ f i r s t ; char∗ l a s t ;} ;

class COEN244 : public Student {public :COEN244( char∗ pF , char∗ pL ) ;~COEN244( ) { count−−; }void setGrade ( f loa t , f loa t , f loa t , f l o a t ) ;v i r t u a l f l o a t grade ( ) ; / / <===s t a t i c i n t getCount ( ) { return count ; }

private :f l o a t assignment ; f l o a t quiz ; f l o a t midterm ; f l o a t f i n a l ;s t a t i c i n t count ;

} ; c© A. Amer Polymorphism 49

Page 69: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Example with virtual functions

void void main {COEN244 c1 ( " Jane " , "Doe" ) ;c1 . setGrade (50 , 55 , 25 , 95 ) ;p r i n t I n f o (&c1 ) ;

}

void p r i n t I n f o ( const Student∗ pStud ) {/ / Output name v ia stream i n s e r t i o n over loadcout << ∗pStud << endl ;cout << pStud−>grade ( ) ; / / grade ( ) o f COEN244 c lass w i l l be c a l l e d

}

c© A. Amer Polymorphism 50

Page 70: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual functions central to OO

Virtual functions make OO software extensible and adaptableBecause old code (in the base class) calls new code (in thederived class)

Programming with classes but without dynamic binding iscalled "object based," but not "object oriented"

c© A. Amer Polymorphism 51

Page 71: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual functions: summary

When a base class member function is declared virtual,it permits run-time (dynamic) selection ofthe equivalent member function of the appropriate derivedclass

c© A. Amer Polymorphism 52

Page 72: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual functions: summary

When a base class member function is declared virtual,it permits run-time (dynamic) selection ofthe equivalent member function of the appropriate derivedclass

Base class virtual functions may have their own definitionIt will be called

if the referenced object is a base class object orif the referenced derived class did not define anequivalent member function

Derived classes defining a virtual function need not beexplicitly declared virtual

Polymorphic behavior works with pointers & references ofbase classes

c© A. Amer Polymorphism 52

Page 73: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual functions: Advice

If using public inheritance,many base class member functions should be declared virtualto ensure that the derived class customizations will overridethe base class behavioreven in a context where a base class object is expected

c© A. Amer Polymorphism 53

Page 74: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Abstract Classes

Some classes represent abstract concepts for which objectscannot exist

(There is no reason to create such objects)

Triangle Rectangle Circle

2DShapePerson

Faculty Student Admine

...

... ...Base Base

Derived Derived Derived Derived DerivedDerived/Base

c© A. Amer Polymorphism 54

Page 75: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Abstract Classes

In an inheritance hierarchy with an abstract base class

The functions have to be defined in the derived classes

The equivalent functions in the base classes are calledpure virtual functions virtual void print() =0;

An object of an abstract base class cannot be instantiated

c© A. Amer Polymorphism 55

Page 76: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Abstract Classes

In an inheritance hierarchy with an abstract base class

The functions have to be defined in the derived classes

The equivalent functions in the base classes are calledpure virtual functions virtual void print() =0;

An object of an abstract base class cannot be instantiated

⇒ Abstract Class: a class with at least one pure virtual function

⇒ Abstract Data Type (ADT): An abstract class

c© A. Amer Polymorphism 55

Page 77: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual destructor

You cannot have virtual constructor, but you can have virtualdestructor

A virtual destructor is a virtual function that is needed if wewill delete (using the delete operator) a derived-class objectvia a base-class pointer

c© A. Amer Polymorphism 56

Page 78: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual destructor

You cannot have virtual constructor, but you can have virtualdestructor

A virtual destructor is a virtual function that is needed if wewill delete (using the delete operator) a derived-class objectvia a base-class pointer

void main ( ) {/ / pStud p o i n t s t o a Student o b j e c tStudent∗ pStud = new COEN244( ” John” , ”Smith” ) ;

. . .delete pStud ; / / w i l l c a l l t h e S tudent o b j e c t ’ s d e s t r u c t o r}

⇒ The COEN244 object destructor will not be calledNot all memory is deallocated!!!

c© A. Amer Polymorphism 56

Page 79: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual destructor

c l a s s Student {fr iend ostream& operator <<(ostream&, Student &) ;public :

Student ( char∗ pF , char∗ pL ) ;v i r t u a l ˜ Student ( ) ;v i r t u a l f l o a t grade ( ) ;

protected : char∗ f i r s t ; char∗ l a s t ;} ;

c© A. Amer Polymorphism 57

Page 80: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual destructor

c l a s s Student {fr iend ostream& operator <<(ostream&, Student &) ;public :

Student ( char∗ pF , char∗ pL ) ;v i r t u a l ˜ Student ( ) ;v i r t u a l f l o a t grade ( ) ;

protected : char∗ f i r s t ; char∗ l a s t ;} ;

⇒ When a Student pointer, pointing to a COEN244 object, isdeleted, the COEN244 destructor is called which in turn willcall the Student destructor

⇒ Virtual destructor violate the rule of virtual functions? (name?)but memory leaks are very dangerous

c© A. Amer Polymorphism 57

Page 81: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual destructor

A class should have a virtual destructor unless that class hasNO virtual functions

If we have any virtual functions, then we will probably going toprocess derived objects via a base pointer

Such processing may include invoking a destructor (normallydone implicitly via delete)

c© A. Amer Polymorphism 58

Page 82: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Virtual destructor

A class should have a virtual destructor unless that class hasNO virtual functions

If we have any virtual functions, then we will probably going toprocess derived objects via a base pointer

Such processing may include invoking a destructor (normallydone implicitly via delete)

Recall virtual functions bind to the code associated with theclass of the object, rather than with the class of thepointer/reference

When you say delete basePtr, and the base class has a virtualdestructor, the destructor that gets invoked is the oneassociated with the type of the object *basePtr, rather thanthe one associated with the type of the pointer

c© A. Amer Polymorphism 58

Page 83: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

P: a summary@

Classes: provides data abstraction and encapsulationa means to hide implementations but document

Inheritance: promotes software reuse

Polymorphism: offers software extensibility

c© A. Amer Polymorphism 59

Page 84: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

class Employee {public :Employee ( const char ∗ , const char ∗ ) ;~Employee ( ) ; / / d e s t r u c t o r rec la ims memoryconst char ∗getFirstName ( ) const ;const char ∗getLastName ( ) const

/ / Pure v i r t u a l f u n c t i o n makes Employee abs t rac t base c lassv i r t u a l double earnings ( ) const = 0; / / pure v i r t u a lv i r t u a l void p r i n t ( ) const ; / / v i r t u a l

private :char ∗ f i rs tName ;char ∗ lastName ;

} ;

c© A. Amer Polymorphism 60

Page 85: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

class Boss : public Employee {public :Boss ( const char ∗ , const char ∗ , double = 0 . 0 ) ;void setWeeklySalary ( double ) ;v i r t u a l double earnings ( ) const ;v i r t u a l void p r i n t ( ) const ;

private :double weeklySalary ;

} ;

c© A. Amer Polymorphism 61

Page 86: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

class SalaryWorker : public Employee {public :

SalaryWorker ( const char ∗ , const char ∗ , double = 0 . 0 ) ;void se tSa la ry ( double ) ;v i r t u a l double earnings ( ) const ;v i r t u a l void p r i n t ( ) const ;

protected :double sa la ry ; / / weekly sa la ry

} ;

c© A. Amer Polymorphism 62

Page 87: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

class HourlyWorker : public Employee {public :

HourlyWorker ( const char ∗ , const char ∗ , double = 0.0 , double = 0 . 0 ) ;void setWage ( double ) ;void setHours ( double ) ;v i r t u a l double earnings ( ) const ;v i r t u a l void p r i n t ( ) const ;

private :double wage ; / / wage per hourdouble hours ; / / hours worked f o r week

} ;

c© A. Amer Polymorphism 63

Page 88: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

class CommissionWorker : public Employee {public :

CommissionWorker ( const char ∗ , const char ∗ , double = 0.0 , i n t = 0 ) ;void setCommission ( double ) ;void se tQuan t i t y ( i n t ) ;v i r t u a l double earnings ( ) const ;v i r t u a l void p r i n t ( ) const ;

protected :double commission ; / / amount per i tem soldi n t q u a n t i t y ; / / t o t a l i tems sold f o r week

} ;

c© A. Amer Polymorphism 64

Page 89: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

/ / Test ingEmployee∗ l i s t [ 10 ] ;

Boss b ( "CCC" , "TTTTT" , 800 .00) ;

CommissionWorker c1 ( "SSSS" , "QQQQ" , 3 .0 , 150) ;CommissionWorker c2 ( " JJJJ " , "DDDD" , 4 .0 , 60 ) ;

SalaryWorker s1 ( "BBBB" , "VVVVV" , 500) ;SalaryWorker s2 ( "RRRR" , "Red" , 500) ;

HourlyWorker h1 ( "GGGG" , "PPPP" , 17.00 , 3 7 . 5 ) ;HourlyWorker h2 ( "KKKK" , " I I I I " , 13.75 , 40 ) ;HourlyWorker h3 ( "MMM" , "TT" , 10.15 , 18 ) ;

c© A. Amer Polymorphism 65

Page 90: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

l i s t [ 0 ] = &b ;l i s t [ 1 ] = &c1 ;l i s t [ 2 ] = &c2 ;l i s t [ 3 ] = &s1 ;l i s t [ 4 ] = &s2 ;l i s t [ 5 ] = &h1 ;l i s t [ 6 ] = &h2 ;l i s t [ 7 ] = &h3 ;

/ / Dynamic Bindingcout << "DYNAMIC BINDING" << endl ;

for ( i n t i = 0 ; i < 8 ; i ++) {l i s t [ i ]−> p r i n t ( ) ; / / using po in te r scout << " earned $ " << (∗ l i s t [ i ] ) . earn ings ( ) ; / / using ob jec ts

c© A. Amer Polymorphism 66

Page 91: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Employee example

/ / S t a t i c Bindingcout << "STATIC BINDING" << endl ;

/ / access through ob jec ts : no polymorphism / v i r t u a l i t yb . p r i n t ( ) ; cout << " earned $ " << b . earn ings ( ) ;c1 . p r i n t ( ) ; cout << " earned $ " << c1 . earn ings ( ) ;c2 . p r i n t ( ) ; cout << " earned $ " << c2 . earn ings ( ) ;s1 . p r i n t ( ) ; cout << " earned $ " << s1 . earn ings ( ) ;s2 . p r i n t ( ) ; cout << " earned $ " << s2 . earn ings ( ) ;

h1 . p r i n t ( ) ; cout << " earned $ " << h1 . earn ings ( ) ;h2 . p r i n t ( ) ; cout << " earned $ " << h2 . earn ings ( ) ;h3 . p r i n t ( ) ; cout << " earned $ " << h3 . earn ings ( ) ;

c© A. Amer Polymorphism 67

Page 92: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Person example

/ / L i s t i n g 15.5 Heterogeneous l i s t processing using v i r t u a l f u n c t i o n sclass Person {

protected :char i d [ 1 0 ] ; / / data common to both typeschar∗ name ; / / v a r i a b l e leng th

public :Person ( const char i d [ ] , const char nm [ ] ) / / Kind type{ s t r cpy ( Person : : id , i d ) ; / / copy i d

name = new char [ s t r l e n (nm) + 1 ] ; / / get space f o r namei f (name == 0) { cout << " Out o f memory \ n " ; e x i t ( 0 ) ; }s t r cpy (name,nm) ; / / copy name

}

v i r t u a l void w r i t e ( ) const / / to d i sp lay data{ } / / not much to do at the moment

~Person ( ) / / r e t u r n heap memory{ delete [ ] name ; } / / f o r Person ob jec t on ly

} ;

c© A. Amer Polymorphism 68

Page 93: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Person example

class Facu l ty : public Person {private :char∗ rank ; / / f o r f a c u l t y on ly

public :Facu l ty ( const char i d [ ] , const char nm[ ] , const char r [ ] )

: Person ( id ,nm) / / i n i t i a l i z a t i o n l i s t{ rank = new char [ s t r l e n ( r ) + 1 ] ;

i f ( rank == 0) { cout << " Out o f memory \ n " ; e x i t ( 0 ) ; }s t r cpy ( rank , r ) ; }

void w r i t e ( ) const / / d i sp lay record{ cout << " i d : " << i d << endl ; / / p r i n t id , name

cout << " name : " << name << endl ;cout << " rank : " << rank <<endl <<endl ; } / / f a c u l t y on ly

~Facu l ty ( ){ delete [ ] rank ; } / / r e t u r n heap memory

} ;

c© A. Amer Polymorphism 69

Page 94: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Person example

class Student : public Person {private :char∗ major ; / / f o r s tudent on ly

public :Student ( const char i d [ ] , const char nm[ ] , const char m[ ] ): Person ( id ,nm) / / i n i t i a l i z a t i o n l i s t{ major = new char [ s t r l e n (m) + 1 ] ;

i f ( major == 0) { cout << " Out o f memory \ n " ; e x i t ( 0 ) ; }s t r cpy ( major ,m) ;

}void w r i t e ( ) const / / d i sp lay record

{ cout << " i d : " << i d << endl ; / / p r i n t id , namecout << " name : " << name << endl ;cout << " major : " << major <<endl <<endl ; / / s tudent on ly

}~Student ( ) { delete [ ] major ; } / / r e t u r n heap memory

} ;

c© A. Amer Polymorphism 70

Page 95: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Person example

void read ( i f s t r eam& f , Person∗& person ) { / / read one recordchar k ind [ 8 ] , i d [ 1 0 ] , name[ 8 0 ] , buf [ 8 0 ] ;f . g e t l i n e ( kind , 8 0 ) ; / / recognize the incoming typef . g e t l i n e ( id , 1 0 ) ; / / read i df . g e t l i n e (name, 8 0 ) ; / / read namef . g e t l i n e ( buf , 8 0 ) ; / / rank or major?i f ( strcmp ( kind , "FACULTY" ) == 0){ person = new Facu l ty ( id , name, buf ) ; } / / ob jec t i s Facu l ty

else i f ( strcmp ( kind , "STUDENT" ) == 0){ person = new Student ( id , name, buf ) ; } / / ob jec t i s Student

else{ cout << " Corrupted data : unknown type \ n " ; e x i t ( 0 ) ; }

}

void w r i t e ( const Person∗ p ) / / d i sp lay record{ p−>w r i t e ( ) ; } / / Facu l ty or Student?

c© A. Amer Polymorphism 71

Page 96: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

Polymorphism: Person example

/ / Test ingcout << endl << endl ;Person∗ data [ 2 0 ] ; i n t cnt = 0 ; / / a r ray o f po in te r s

i f s t r eam from ( " un iv . dat " ) ; / / i npu t data f i l ei f ( ! from ) { cout << " Cannot open f i l e \ n " ; return 0; }while ( ! from . eof ( ) )

{ read ( from , data [ cn t ] ) ; / / read u n t i l eofcnt ++; }

cout << " To ta l records read : " << cnt << endl << endl ;

for ( i n t i =0; i < cnt ; i ++){ w r i t e ( data [ i ] ) ; } / / d i sp lay data

for ( i n t j =0; j < cnt ; j ++){ delete data [ j ] ; } / / de le te the record

c© A. Amer Polymorphism 72

Page 97: Aishy Amer - EncsStatic polymorphism: compile-time type and function checking Dynamic polymorphism: run-time type and function checking Virtual functions: can be over-riddenat run

A sample exam’s problem

Define a XXXX class that inherits from XXXX class ...

Declare base pointers each pointing to a derived object ...

...

Pay attention to the type of the pointer ...

To be continued in class.

c© A. Amer Polymorphism 73