c++ programming: polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_polymorphism.pdf · 5...

42
C++ Programming: Polymorphism 2019년도 2학기 Instructor: Young-guk Ha Dept. of Computer Science & Engineering

Upload: others

Post on 10-Mar-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

C++ Programming:

Polymorphism

2019년도 2학기

Instructor: Young-guk HaDept. of Computer Science & Engineering

Page 2: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Contents

• Run-time binding in C++

• Abstract base classes

• Run-time type identification

2

Page 3: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Function Binding in C++• Function binding

– To associate a function’s name with its entry point, which is the starting address of the code that implements the function

• Types of function binding in C++– Compile-time binding

• To bind any invocation of a function to its entry point when the program is being compiled

• I.e., compiler determines what code is to be executed

• Has been in effect throughout our examples so far

– Run-time binding• The alternative of the compile-time binding

• To bind a function when the program is running3

Page 4: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Polymorphism• In C++, polymorphism is run-time binding of methods

– I.e., a method is polymorphic if its binding occurs at run-time rather than compile-time

• A powerful tool for programmers– A programmer can invoke an object’s polymorphic method

without knowing exactly which class type or subtype is involved

– E.g., a Window class hierarchy• Imagine a base class Window and its 20 or so derived classes• Each class has a polymorphic display method with the same

signature, which performs some class-specific operation• The programmer needs to remember only one method signature

to invoke 20 or so different methods

4

Page 5: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

5

Example of Polymorphism• Various versions of the display method

– Base class Window has a display method to draw basic window frames on the screen

– MenuWindow has a display to show a list of choices in addition– Each Window class has its own version of display method

• A client can invoke a single display method for any type of Window at runtime– E.g., w->display();

• If w points to a Windowobject, its display is invoked

• Else if w points to a MenuWindowor DialogWindow object,each display is invoked

v Note that what version of displayto be invoked is determined at runtime(not compile time)

Window

MenuWindow DialogWindow …

InformationDialog …

::display()

::display() ::display()

::display()

Window* w

Page 6: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Requirements for C++ Polymorphism

• Three requirements for implementation of polymorphism in C++1) When defining classes with polymorphic methods

– All the classes must be in the same inheritance hierarchy

2) When defining polymorphic methods– The methods must be virtual and have the same signature

3) When using polymorphic methods– There must be a pointer of base class, which is used to invoke the virtual methods

– No cast is required when assigning a pointer of base class to an object of derived class (* note that a pointer of base class may point to an object of any derived class)

6

Page 7: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Polymorphism Example// base classclass TradesPerson {public:virtual void sayHi() {

cout << “Just hi.” << endl; }};

// derived class 1class Tinker : public TradesPerson { public:virtual void sayHi() {

cout << “Hi, I tinker.” << endl; }

};

// derived class 2class Tailor : public TradesPerson {public:virtual void sayHi() {

cout << “Hi, I tailor.” << endl; }

};

int main() {// pointer to base classTradesPerson* p;int which;do {cout << “1 == TradesPerson, ”<< “2 == Tinker, 3 == Tailor “;cin >> which;

} while (which < 1 || which > 3);

// set p depending on user choiceswitch (which) {

case 1: p = new TradesPerson; break;

case 2: p = new Tinker; break;case 3: p = new Tailor; break;

}

// run-time binding in effect p->sayHi();

delete p; // free the storage}

7

Page 8: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Polymorphism Example (cont.)

8

TradesPerson *p

p->sayHi();Just hi.

*p p->sayHi();Hi, I tinker.

*p p->sayHi();Hi, I tailor.

TradesPerson

Tinker Tailor

TradesPerson Object• virtual void sayHi();

Tinker Object• virtual void sayHi();

Tailor Object• virtual void sayHi();

Page 9: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Implicit virtual Methods• Using keyword virtual in all the polymorphic

methods is not a requirement– If a base class method is declared virtual, any derived class

method with the same signature is automatically declared virtual, even if not explicitly declared

– E.g., in the previous example, keyword virtual in front of method Tinker::sayHi can be omitted

class TradesPerson {public:

virtual void sayHi() { cout << "Just hi." << endl; }};

class Tinker : public TradesPerson {public:

void sayHi() { cout << "Hi, I tinker." << endl; }};... 9

Page 10: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Notices on Using Keyword virtual• In case of defining a virtual method outside the class, the keyword

virtual occurs only in the method’s declaration, not in its definition

• Top-level functions can not be virtual, only methods can be virtual

class C {public:

virtual void m(); // declaration: "virtual" occurs...

};

void C::m() { // definition: no "virtual"...

}

virtual void f(); // ERROR: not a method!int main() {

...}

10

Page 11: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Inheriting virtual Methods• virtual methods can be inherited from base classes

to derived classes just like common methods– E.g., class Tinker does not provide its own definition of sayHi, it inherits sayHi from its base class TradesPerson

class TradesPerson {public:

virtual void sayHi(){ cout << "Just hi." << endl; }};

class Tinker : public TradesPerson {... // no Tinker’s sayHi defined

};

int main() {Tinker t1;t1.sayHi(); // inherited TradesPerson’s sayHi...

}

Just hi.

11

Page 12: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

The Vtable• OOP languages commonly use the vtable (virtual table)

to implement run-time binding– Implementation of vtable is system-dependent

– The purpose of vtable is to support run-time lookup of a particular entry point for a function’s name

– Thus, a program using run-time binding incurs performance penalty due to vtable lookup

• Space: amount of storage for the vtable

• Time: time taken for vtable lookup

• E.g., Smalltalk vs. C++– In a pure OOP language such as Smalltalk, all methods are

polymorphic by default à suffers from heavy performance penalty

– In C++, programmer can choose polymorphic (virtual) methodsà smaller performance penalty

12

Page 13: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Vtable Exampleclass B { // base classpublic:virtual void m1() { ... }virtual void m2() { ... }

};

class D : public B { // derived classpublic:virtual void m2() { ... }

};

int main() {B b; // base class objectD d; // derived class objectB* p; // pointer to base class

p = &b; // p is set to b’s addressp->m2(); // vtable lookup for run-time binding

p = &d; // p is set to d’s addressp->m2(); // vtable lookup for run-time binding

}

virtualMethod Name Entry Point

b.m1

b.m2d.m2

0x77230x23b40x99a7

[ Vtable ]

13

Page 14: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Constructors and Destructors

• Constructors CAN NOT be virtual,but destructor CAN be virtual

class C {

public:

virtual C(); // ERROR: a constructorvirtual C(int a); // ERROR: a constructorvirtual ~C(); // OK: a destructorvirtual void m(); // OK: a regular method

};

14

Page 15: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

virtual Destructors

• In some cases, destructors should be made virtual to ensure that polymorphism is at work for the destructors of the derived classes– E.g., if a derived class has

• a data member that points to dynamically allocated storage

• and the destructor to free such storage

à “storage leakage problem“ can occur when handling the derived class with a pointer to its base class (refer to the next example)

v In commercial libraries (e.g., MFC), destructors are typically virtual to prevent such problem

15

Page 16: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

virtual Destructors Example• Example codes of the storage leakage problem

void f() {

A* ptr;// type of ptr is pointer // of the base class A

ptr = new Z();// both A() and Z() fire// à a Z object is created

delete ptr;// only ~A() fires, not ~Z()

// à no polymorphism// (ptr is a pointer of// class A)

} // Caution: results in 5,000 bytes // of leaked storage

class A {public:A() {

p = new char[5];}~A() {

delete[] p; // free p}...

};

class Z : public A {public:Z() {

q = new char[5000];}~Z() {

delete[] q; // free q}...

};16

Page 17: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

virtual Destructors Example (cont.)• The previous problem can be fixed by making the

destructors virtual– By making the base class destructor ~A() virtual, we can

make derived class destructor ~Z() virtual implicitly

class A {public:...virtual ~A() { // virtual destructor

// à ~Z() becomes virtual as welldelete[ ] p;

}...

};

void f() {...delete ptr; // ~Z() fires and then ~A() fires

// à checks what ptr actually points to,... // not the type of ptr

}

A() firing

Z() firing

~Z() firing

~A() firing

17

Page 18: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Class Methods and Run-Time Biding

• static methods (class methods) can not be virtual– Because static methods are bound only at the compile

time

class C {

public:

// ERROR: static and virtualstatic virtual void f();

static void g(); // OK, not virtualvirtual void h(); // OK, not static

};

18

Page 19: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Other C++ Constructs ThatResemble Run-Time Binding

• In C++, only virtual methods are bound at run-time– Only virtual methods are truly polymorphic

• C++ has some other constructs that resemble run-time binding but are quite distinct from it (actually, compile-time binding)– Name overloading (both methods and functions)– Name overriding– Name hiding

19

Page 20: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Name Overloading• When top-level functions or methods in the same

class share one name, but have different signatures

class C {public:

C() { ... } // default constructorC(int x) { ... } // convert constructor

};

void f(double d) { ... }void f(char C) { ... }

int main() {C c1; // default constructor calledC c2(26); // convert constructor calledf(3.14); // f(double) is bound by compilerf('z’); // f(char) is bound by compiler

}

20

Page 21: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Name Overriding• When a base class and its derived class have methods

with the same signature (not declared virtual)

class B { // base classpublic:void m() { cout << "B::m" << endl; }

}; // m is not virtual

class D : public B { // derived classpublic:void m() { cout << "D::m" << endl; }

}; // overrides B::m

int main() {

D q;q.m(); // invokes D::m

// (D::m overrides B::m)B* p;p = &q;p->m(); // invokes B::m (not D::m)

}

// if B::m is declared virtualclass B { // base classpublic:virtual void m()

{ cout << "B::m" << endl; }};

...

int main() {...

B* p;

p = &q;

p->m(); // invokes D::m// (polymorphism)

}

21

Page 22: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Name Hiding• When a base class and its derived class have methods

with the same name and different signatures

class B {

public:

void m(int x) { cout << x << endl; }

};

class D : public B {

public:

void m() { cout << "Hi" << endl; }

};

int main() {

D d;

d.m(); // OK

d.m(26); // Error: B’s m(int) is hidden by D’s m()

// to correct, use d1.B::m(26)

return 0;

} 22

Page 23: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Name Sharings in C++

• Polymorphism– Between virtual methods of classes in the same hierarchy

– Have the same signature

• Name overriding– Between methods (not virtual) of classes in the same hierarchy

– Have the same signature

• Name hiding– Between methods (not virtual) of classes in the same hierarchy

– Have the same name but different signatures

• Name overloading– Between methods in the same class or top-level functions– Have the same name but different signatures

23

üCompile

timebinding

üRuntime

binding

Page 24: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Another Usage of virtual:Shared Interfaces

• In OO design, sometimes, it is required that different classes must commonly define a collection of specific methods– It is called shared interface (e.g., interface in Java)– E.g., a Window class hierarchy designer may want to ensure

that each derived class in the hierarchy defines its own display, close, and move methods

• We can use a kind of virtual methods to enforce derived classes to define those methods – They are called “pure virtual methods”– Remember that common virtual methods could be, but

need not be overridden in derived classes24

Page 25: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Pure virtual Methods• “Pure“ virtual methods

– Methods that any derived classes must override in order to instantiate their objects

• Declarations end with the special syntax “=0”

• Have no definitions

// a class with pure virtual methodsclass ABC {public:virtual void open() = 0;virtual void close() = 0;virtual void flush() = 0;

};

25

Page 26: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Abstract Base Classes• What is an abstract base class (ABC)

– A class that has one of more pure virtual methods• Just one pure virtual method is enough to make a class

abstract

– ABCs can NOT instantiate their objects– ABC is typically used as a shared interface in C++

26

class ABC { // Abstract Base Classpublic:

virtual void open() = 0;...

};

ABC obj; // ERROR: ABC is an abstract class

Page 27: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

ABC and Derived Classes• Although an ABC can not have any object that instantiates it, it

can have derived classes– Classes derived from an ABC

• MUST override all the pure virtual methods inherited from ABC

• Otherwise, the derived classes also become abstract and no objects can instantiate them

class ABC { // Abstract Base Classpublic: virtual void open() = 0;};

class X : public ABC { // 1st derived classpublic: virtual void open() { ... } // overrides open()};

class Y : public ABC { // 2nd derived class// *** open is not overridden

};

ABC a1; // *** ERROR: ABC is abstractX x1; // *** OK, X overrides open() and is not abstractY y1; // *** ERROR: Y is also abstract à open() is not defined 27

Page 28: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

ABC and Other Members• ABCs may have other members than pure virtual methods,

which can be normally inherited– Data members– Constructors and destructors– Ordinary methods and common virtual methods

class ABC { // Abstract Base Classpublic:

ABC() { ... } // constructorABC(int x) { ... } // constructor~ABC() { ... } // destructorvirtual void open() = 0; // pure virtualvirtual void print() const { ... } // virtualint getCount() const { return n; } // nonvirtual

private:int n; // data member

};

28

Page 29: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Restriction on UsingPure Declarations

• Only virtual methods can be pure– Neither nonvirtual methods nor top-level

functions can be declared pure

29

void f() = 0; // **** ERROR: not a method

class C {

public:

void open() = 0; // **** ERROR: not virtual...

};

Page 30: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Usage of ABC (1)class IFile { // file interfacepublic:virtual void open() = 0;virtual void close() = 0;

virtual void flush() = 0;};

class TextFile : public IFile {

public:

virtual void open() { ... } // to open a text filevirtual void close() { ... } // to close a text filevirtual void flush() { ... } // to flush a text file

};

class BinaryFile : public IFile {public:

virtual void open() { ... } // to open a binary filevirtual void close() { ... } // to close a binary filevirtual void flush() { ... } // to flush a binary file

};30

Page 31: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Usage of ABC (2)

• To specify program design requirements– E.g., introspection methods for a big project

• Large number of programmers: each programmer is responsible for a lot of classes

• During the design phase, the PM decided that each class should have two public methods to introspect the class

• Such design decision can be enforced by using an ABC

class IIntrospect { // introspection interface

public:

virtual void listData() = 0; // prints data members info.

virtual void listMethods() = 0; // prints methods info.

}

31

Page 32: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Run-Time Type Identification

• C++ supports run-time type identification,

which provides the following mechanisms

– To check if type conversion is safe at run time

• Using dynamic_cast operator

– To determine type of object or class at run time

• Using typeid operator

32

Page 33: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Dynamic Cast

• Previously discussed cast operators in C++– static_cast

• Can be applied to any type (polymorphic or not)– E.g., Converting int a to float b

“b = static_cast<float>(a)” == “b = (float)a”

• Static cast (at compile-time) does NOT ensure type safety at run-time

– const_cast• Used to cast away constness of a pointer to a const object

– reinterpret_cast• Used to convert from a pointer of one type to a pointer of another type

• dynamic_cast– The dynamic cast operator tests whether a cast involving objects is

type safe or not at run-time

33

Page 34: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Type Safety Problem of static_cast at Run-Time

class B {public:virtual void f() { ... }// note: no method m

};

class D : public B {public:void m() { ... } // additional method m of class D

};

int main() {D* p; // pointer to derived classp = new B; // compile-time error: cast required

p = static_cast<D*>(new B); // legal but dealt w/ cautionp->m(); // run-time error: even though p is a pointer of D

// it actually points to a B object};

A derived classpointer

actually points to a base class

object

34

Page 35: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Type Safety Problem Illustrated

35

B_Object

void f();

D* p;

X

D_Object

void f();

D* p;

void m();

B_Object

void f();

static_cast<D*>(&B_Object)

D_Object

void f();

void m();

p->m();

D* p;

Page 36: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

dynamic_cast to Resolve Type Safety Problem

• C++ provides dynamic_cast operator to check at run-time whether a cast is type safe or not

dynamic_cast<target_type_ptr>(source_obj_ptr)• Evaluates to target_obj_ptr (= true), if the cast is type safe• Evaluates to 0 (= NULL or false), if the cast is not type safe

– Notices on using dynamic_cast• A dynamic_cast is legal only for polymorphic types

– The source type (type of source_obj_ptr) must have a virtualmethod

– The target type and the source type must be on the same inheritance hierarchy

• Target type must be specified as a pointer or a reference– dynamic_cast<T>(ptr) à Error– dynamic_cast<T*>(ptr) à OK

36

Page 37: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

dynamic_cast Exampleclass B {

public:

virtual void f() { ... }

};

class D : public B {

public:

void m() { ... }

};

int main() {

D* p; // pointer to derived class

p = dynamic_cast<D*>(new B);

if (p) p->m(); // if type safe then invoke p->m()

else cerr << “Error: not safe” << endl;

};

Error: not safe

37

Page 38: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Checking Parameter’s Type at Run-Time with dynamic_cast

class Fiction class Textbook

class Book

virtual void printTitle()

virtual void printTitle()void printLevel()

virtual void printTitle()

void printBookInfo(Book* bookPtr)

Textbook* ptr = static_cast<Textbook*>(bookPtr);ptr->printLevel(); è not safe

38

Page 39: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Checking Parameter’s Type at Run-Time with dynamic_cast (cont.)class Book {public:virtual void printTitle() const { ... }...

}

class Textbook : public Book {public:void printTitle() const { ... }void printLevel() const { ... }...

}

class Fiction : public Book {public:void printTitle() const { ... }...

}

void printBookInfo(Book* bookPtr) {bookPtr->printTitle(); // print title in any caseTextbook* ptr = dynamic_cast<Textbook*>(bookPtr);if (ptr) ptr->printLevel(); // invoke printLevel if type safe

}39

Page 40: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

The Rules for dynamic_cast• Simple rules for dynamic_cast

– dynamic_cast from a directly or indirectly derived type to a base type succeeds (upcast)

• E.g., dynamic_cast<B*>(new D1) will succeed

– dynamic_cast from a base type to a directly or indirectly derived type may fail (downcast)

• E.g., dynamic_cast<D1*>(new B) may fail

– dynamic_cast between unrelated types (other than void) fails• E.g., dynamic_cast<D1*>(new Z) or vice versa will fail

D1

B Z

upca

st

dow

ncas

t

40D2 D3

: success: fail: may fail

Page 41: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Run-Time Type Determination with the typeid Operator

• The typeid operator is used to determine an expression’s type at run-time

typeid(typename | expression)• Returns a reference to a type_info object that represents the given typename or expression

• “typeinfo“ header needs to be included first

– E.g., given “float x“ and “long val”

typeid Statement Evaluationtypeid( x ) == typeid( float )

typeid( x ) == typeid( double )typeid( x ) == typeid( float* )

typeid( val ) == typeid( long )typeid( val ) == typeid( short )typeid( 5280 ) == typeid( int )

typeid( 9.21883E-9L ) == typeid( long double )

true

falsefalse

truefalsetrue

true 41

Page 42: C++ Programming: Polymorphismsclab.konkuk.ac.kr/attachments/lecture/3/05_Polymorphism.pdf · 5 Example of Polymorphism •Various versions of the displaymethod –Base class Windowhas

Run-Time Type Determination with the typeid Operator (cont.)

• E.g., given the previous Book class hierarchy and the following declaration

Book* bookPtr = new Textbook(“test”, 1);

typeid Statement Evaluation

typeid( bookPtr ) == typeid( Book* )

typeid( bookPtr ) == typeid( Textbook* )

typeid( *bookPtr ) == typeid( Book )

typeid( *bookPtr ) == typeid( Textbook )

true

false

false

true

42