C++ Programming: Polymorphism

Similar documents
POLYMORPHISM 2 PART Abstract Classes Static and Dynamic Casting Common Programming Errors

POLYMORPHISM 2 PART. Shared Interface. Discussions. Abstract Base Classes. Abstract Base Classes and Pure Virtual Methods EXAMPLE

Polymorphism. Zimmer CSCI 330

What is Polymorphism? Quotes from Deitel & Deitel s. Why polymorphism? How? How? Polymorphism Part 1

Polymorphism Part 1 1

Polymorphism. Miri Ben-Nissan (Kopel) Miri Kopel, Bar-Ilan University

Increases Program Structure which results in greater reliability. Polymorphism

VIRTUAL FUNCTIONS Chapter 10

C++ Crash Kurs. Polymorphism. Dr. Dennis Pfisterer Institut für Telematik, Universität zu Lübeck

Cpt S 122 Data Structures. Course Review Midterm Exam # 2

OBJECT ORIENTED PROGRAMMING USING C++

Inclusion Polymorphism

QUIZ. Write the following for the class Bar: Default constructor Constructor Copy-constructor Overloaded assignment oper. Is a destructor needed?

Intro to OOP Visibility/protection levels and constructors Friend, convert constructor, destructor Operator overloading a<=b a.

Inheritance, Polymorphism and the Object Memory Model

Tokens, Expressions and Control Structures

C++ Programming: Introduction to C++ and OOP (Object Oriented Programming)

Dynamic Binding C++ Douglas C. Schmidt

Data Abstraction. Hwansoo Han

Strict Inheritance. Object-Oriented Programming Spring 2008

Object Oriented Software Design II

(12-1) OOP: Polymorphism in C++ D & D Chapter 12. Instructor - Andrew S. O Fallon CptS 122 (April 3, 2019) Washington State University

OBJECT ORIENTED PROGRAMMING USING C++ CSCI Object Oriented Analysis and Design By Manali Torpe

Object Oriented Software Design II

Strict Inheritance. Object-Oriented Programming Winter

Fast Introduction to Object Oriented Programming and C++

Introduction to C++ Introduction to C++ Dr Alex Martin 2013 Slide 1

Where do we stand on inheritance?

Dr. Md. Humayun Kabir CSE Department, BUET

04-24/26 Discussion Notes

COMP322 - Introduction to C++ Lecture 09 - Inheritance continued

CS201 - Introduction to Programming Glossary By

엄현상 (Eom, Hyeonsang) School of Computer Science and Engineering Seoul National University COPYRIGHTS 2017 EOM, HYEONSANG ALL RIGHTS RESERVED

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

Polymorphism. Contents. Assignment to Derived Class Object. Assignment to Base Class Object

Object Oriented Programming. Solved MCQs - Part 2

JAYARAM COLLEGE OF ENGINEERING AND TECHNOLOGY Pagalavadi, Tiruchirappalli (An approved by AICTE and Affiliated to Anna University)

Short Notes of CS201

Chapter 5 Object-Oriented Programming

Note 12/1/ Review of Inheritance Practice: Please write down 10 most important facts you know about inheritance...

C++ without Classes. CMSC433, Fall 2001 Programming Language Technology and Paradigms. More C++ without Classes. Project 1. new/delete.

15: Polymorphism & Virtual Functions

Introduction to Programming Using Java (98-388)

CS105 C++ Lecture 7. More on Classes, Inheritance

These new operators are intended to remove some of the holes in the C type system introduced by the old C-style casts.

ECE 3574: Dynamic Polymorphism using Inheritance

What is Inheritance?

Practice for Chapter 11

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

CMSC 202 Section 010x Spring Justin Martineau, Tuesday 11:30am

G Programming Languages - Fall 2012

Jayaram college of Engineering and Technology, Pagalavadi. CS2203 Object Oriented Programming Question Bank Prepared By: S.Gopalakrishnan, Lecturer/IT

Design issues for objectoriented. languages. Objects-only "pure" language vs mixed. Are subclasses subtypes of the superclass?

CMSC 132: Object-Oriented Programming II

Object-Oriented Languages and Object-Oriented Design. Ghezzi&Jazayeri: OO Languages 1

Inheritance & Polymorphism. Object-Oriented Programming Spring 2015

OOP THROUGH C++(R16) int *x; float *f; char *c;

C++ Casts and Run-Time Type Identification

Object Oriented Programming is a programming method that combines: Advantage of Object Oriented Programming

PIC 10A Pointers, Arrays, and Dynamic Memory Allocation. Ernest Ryu UCLA Mathematics

Preface to the Second Edition Preface to the First Edition Brief Contents Introduction to C++ p. 1 A Review of Structures p.

CPS 506 Comparative Programming Languages. Programming Language

Introduction to RTTI. Jonathan Hoyle Eastman Kodak 11/30/00

Concepts of Programming Languages

Chapter 2. Procedural Programming

Programming C++ Lecture 5. Howest, Fall 2013 Instructor: Dr. Jennifer B. Sartor

Instantiation of Template class

A <Basic> C++ Course

Variables. Data Types.

Data type of a pointer must be same as the data type of the variable to which the pointer variable is pointing. Here are a few examples:

Inheritance, and Polymorphism.

CS11 Advanced C++ Fall Lecture 7

Argument Passing All primitive data types (int etc.) are passed by value and all reference types (arrays, strings, objects) are used through refs.

W3101: Programming Languages C++ Ramana Isukapalli

Course Text. Course Description. Course Objectives. StraighterLine Introduction to Programming in C++

Extending Classes (contd.) (Chapter 15) Questions:

OOPs Concepts. 1. Data Hiding 2. Encapsulation 3. Abstraction 4. Is-A Relationship 5. Method Signature 6. Polymorphism 7. Constructors 8.

What are the characteristics of Object Oriented programming language?

Making Inheritance Work: C++ Issues

Making Inheritance Work: C++ Issues

C How to Program, 6/e by Pearson Education, Inc. All Rights Reserved.

C++ Inheritance II, Casting

Polymorphism. Arizona State University 1

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

Absolute C++ Walter Savitch

Compaq Interview Questions And Answers

CS3157: Advanced Programming. Outline

COMP322 - Introduction to C++

Introduction to C++ Systems Programming

C++ Inheritance and Encapsulation

C++ Programming: Inheritance

Written by John Bell for CS 342, Spring 2018

Exercise: Singleton 1

Selected Java Topics

Virtual functions concepts

INHERITANCE & POLYMORPHISM. INTRODUCTION IB DP Computer science Standard Level ICS3U. INTRODUCTION IB DP Computer science Standard Level ICS3U

Laboratorio di Tecnologie dell'informazione

Laboratorio di Tecnologie dell'informazione. Ing. Marco Bertini

OBJ. ORI.& MULT. PROG., M.C.Q. BANK, FOR UNIT -2, SECOND YEAR COMP. ENGG. SEM-4, 2012 PATTERN, U.O.P. UNIT-2

Object-Oriented Programming, Iouliia Skliarova

Transcription:

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

Contents Run-time binding in C++ Abstract base classes Run-time type identification 2

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 running 3

Polymorphism 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

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 Window object, its display is invoked Else if w points to a MenuWindow or DialogWindow object, each display is invoked Window* w Window ::display() MenuWindow DialogWindow ::display() ::display() Note that what version of display to be invoked is determined at runtime (not compile time) InformationDialog ::display() 5

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

Polymorphism Example // base class class TradesPerson { virtual void sayhi() { cout << Just hi. << endl; } // derived class 1 class Tinker : public TradesPerson { virtual void sayhi() { cout << Hi, I tinker. << endl; } // derived class 2 class Tailor : public TradesPerson { virtual void sayhi() { cout << Hi, I tailor. << endl; } int main() { // pointer to base class TradesPerson* p; int which; do { cout << 1 == TradesPerson, << 2 == Tinker, 3 == Tailor ; cin >> which; } while (which < 1 which > 3); } // set p depending on user choice switch (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

Polymorphism Example (cont.) TradesPerson Object virtual void sayhi(); TradesPerson TradesPerson *p p->sayhi(); Just hi. Tinker Tailor Tinker Object virtual void sayhi(); Tailor Object virtual void sayhi(); *p p->sayhi(); Hi, I tinker. *p p->sayhi(); Hi, I tailor. 8

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 { virtual void sayhi() { cout << "Just hi." << endl; } class Tinker : public TradesPerson { void sayhi() { cout << "Hi, I tinker." << endl; }... 9

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 class C { virtual void m(); // declaration: "virtual" occurs... void C::m() {... } // definition: no "virtual" Top-level functions can not be virtual, only methods can be virtual virtual void f(); int main() {... } // ERROR: not a method! 10

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 { 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

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

Vtable Example class B { // base class virtual void m1() {... } virtual void m2() {... } class D : public B { // derived class virtual void m2() {... } int main() { B b; // base class object D d; // derived class object B* p; // pointer to base class virtual Method Name b.m1 b.m2 d.m2 [ Vtable ] Entry Point 0x7723 0x23b4 0x99a7 } p = &b; // p is set to b s address p->m2(); // vtable lookup for run-time binding p = &d; // p is set to d s address p->m2(); // vtable lookup for run-time binding 13

Constructors and Destructors A constructor can NOT be virtual, but a destructor CAN be virtual class C { virtual C(); virtual C(int a); virtual ~C(); virtual void m(); // ERROR: a constructor // ERROR: a constructor // OK: a destructor // OK: a regular method 14

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) In commercial libraries (e.g., MFC), destructors are typically virtual to prevent such problem 15

virtual Destructors Example Example codes of the storage leakage problem class A { A() { p = new char[5]; } ~A() { }... delete[] p; // free p class Z : public A { Z() { q = new char[5000]; } ~Z() { }... delete[] q; // free q 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 16

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 {... virtual ~A() { delete[ ] p; }... // virtual destructor // ~Z() becomes virtual as well 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

Class Methods and Run-Time Biding static methods (class methods) can not be virtual class C { // ERROR: static and virtual static virtual void f(); static void g(); // OK, not virtual virtual void h(); // OK, not static 18

Other C++ Constructs That Resembles 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 runtime binding but are quite distinct from it (actually, compile-time binding) Name overloading (both methods and functions) Name overriding Name hiding 19

Name Overloading When top-level functions or methods in the same class share one name, but have different signatures class C { C() {... } // default constructor C(int x) {... } // convert constructor void f(double d) {... } void f(char C) {... } int main() { C c1; C c2(26); f(3.14); f('z ); } // default constructor called // convert constructor called // f(double) is bound by compiler // f(char) is bound by compiler 20

Name Overriding When a base class and its derived class have methods with the same signature (not declared virtual) class B { // base class void m() { cout << "B::m" << endl; } // m is not virtual class D : public B { // derived class void m() { cout << "D::m" << endl; } // overrides B::m int main() { } D q; q.m(); B* p; p = &q; p->m(); // invokes D::m // (D::m overrides B::m) // invokes B::m (not D::m) // if B::m is declared virtual class B { // base class virtual void m() { cout << "B::m" << endl; }... int main() { }... B* p; p = &q; p->m(); // invokes D::m // (polymorphism) 21

Name Hiding When a base class and its derived class have methods with the same name and different signatures class B { void m(int x) { cout << x << endl; } class D : public B { 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

Name Sharings in C++ Run time binding 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 Compile time binding 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

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 (cf. 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 (override) those methods Note that generic virtual methods could be, but need not be overridden in derived classes class B { // base class virtual void m() {... } class D : public B { // derived class //... no m() is defined in D // thus B::m is just inherited (need not be overridden) 24

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 methods class ABC { virtual void open() = 0; virtual void close() = 0; virtual void flush() = 0; 25

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 suffices to make a class abstract ABCs can NOT instantiate their objects because they are abstract ABC is typically used as a shared interface in C++ class ABC { // Abstract Base Class virtual void open() = 0;... ABC obj; // ERROR: ABC is an abstract class 26

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 of the ABC s pure virtual methods Otherwise, the derived classes also become abstract and no objects can instantiate them class ABC { // Abstract Base Class virtual void open() = 0; class X : public ABC { // 1st derived class virtual void open() {... } // overrides open() class Y : public ABC { // 2nd derived class // *** open is not overridden ABC a1; // *** ERROR: ABC is abstract X x1; // *** OK, X overrides open() and is not abstract Y y1; // *** ERROR: Y is also abstract open() is not defined 27

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 virtual methods class ABC { // Abstract Base Class ABC() {... } ABC(int x) {... } ~ABC() {... } virtual void open() = 0; virtual void print() const {... } int getcount() const { return n; } private: int n; // constructor // constructor // destructor // pure virtual // virtual // nonvirtual // data member 28

Restriction on Pure Declarations Only virtual methods can be pure Neither nonvirtual methods nor top-level functions can be declared pure void f() = 0; // **** ERROR: not a method class C { void open() = 0; // **** ERROR: not virtual... 29

Usage of ABC (1) class IFile { // file interface virtual void open() = 0; virtual void close() = 0; virtual void flush() = 0; class TextFile : public IFile { virtual void open() {... } virtual void close() {... } virtual void flush() {... } class BinaryFile : public IFile { virtual void open() {... } virtual void close() {... } virtual void flush() {... } // to open a text file // to close a text file // to flush a text file // to open a binary file // to close a binary file // to flush a binary file 30

Usage of ABC (2) To specify program design requirements E.g., introspection methods for a big project A large number of programmers: each programmer is responsible for a number 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 virtual void listdata() = 0; // prints data members info. virtual void listmethods() = 0; // prints methods info. } 31

Run-Time Type Identification C++ supports run-time type identification, which provides 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

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 at run-time whether a cast involving objects is type safe or not 33

Type Safety Problem of static_cast at Run-Time A derived class pointer actually points to a base class object class B { virtual void f() {... } // note: no method m class D : public B { void m() {... } // additional method m of class D int main() { D* p; // pointer to derived class p = new B; // compile-time error: cast required p = static_cast<d*>(new B); // legal but dealt w/ caution p->m(); // run-time error: even though p is a pointer of D // it actually points to a B object 34

Type Safety Problem Illustrated D* p; X B_Object D* p; D_Object D* p; D_Object void f(); void f(); void m(); void f(); void m(); static_cast<d*>(&b_object) B_Object p->m(); void f(); 35

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 virtual method 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

dynamic_cast Example class B { virtual void f() {... } class D : public B { void m() {... } Error: not safe 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; 37

Checking Parameter s Type at Run-Time with dynamic_cast virtual void printtitle() class Book class Fiction virtual void printtitle() class Textbook virtual void printtitle() void printlevel() void printbookinfo(book* bookptr) invokes bookptr->printtitle() invokes bookptr->printlevel() not safe 38

Checking Parameter s Type at Run- Time with dynamic_cast (cont.) class Book { virtual void printtitle() const {... }... } class Textbook : public Book { void printtitle() const {... } void printlevel() const {... }... } class Fiction : public Book { void printtitle() const {... }... } void printbookinfo(book* bookptr) { bookptr->printtitle(); // print title in any case Textbook* ptr = dynamic_cast<textbook*>(bookptr); if (ptr) ptr->printlevel(); // invoke printlevel if type safe } 39

downcast upcast 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 B Z D1 : success D2 D3 : fail : may fail 40

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 typeid( 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 ) Evaluation true false false true false true true 41

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