Polymorphism, Virtual Methods and Abstract Classes.

Slides:



Advertisements
Similar presentations
Polymorphism and Virtual Functions. Topics Polymorphism Virtual Functions Pure Virtual Functions Abstract Base Classes Virtual Destructors V-Tables Run.
Advertisements

Inheritance. Topics Inheritance Constructors and Inheritance Overriding Functions and Variables Designing with Inheritance.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Rossella Lau Lecture 8, DCO10105, Semester B, DCO10105 Object-Oriented Programming and Design  Lecture 8: Polymorphism & C++ pointer  Inheritance.
1 Chapter 7 l Inheritance Basics l Programming with Inheritance l Dynamic Binding and Polymorphism Inheritance.
Pointers and Dynamic Variables. Objectives on completion of this topic, students should be able to: Correctly allocate data dynamically * Use the new.
Templates. Objectives At the conclusion of this lesson, students should be able to Explain how function templates are used Correctly create a function.
12/08/08MET CS Fall Polymorphism 10. Polymorphism Goal: Goal: Create methods that can be invoked with all object types, base as well as.
C++ Polymorphism Systems Programming. Systems Programming: Polymorphism 2   Polymorphism Examples   Relationships Among Objects in an Inheritance.
Vocabulary Key Terms polymorphism - Selecting a method among many methods that have the same name. subclass - A class that inherits variables and methods.
Shallow Versus Deep Copy and Pointers Shallow copy: when two or more pointers of the same types point to the same memory – They point to the same data.
Computer Science and Software Engineering University of Wisconsin - Platteville 7. Inheritance and Polymorphism Yan Shi CS/SE 2630 Lecture Notes.
Chapter 4 Inheritance Bernard Chen Spring Objective IS-A relationships and the allowable changes for derived classes The concept of polymorphism.
C++ Object Oriented 1. Class and Object The main purpose of C++ programming is to add object orientation to the C programming language and classes are.
Learners Support Publications Pointers, Virtual Functions and Polymorphism.
Cpt S 122 – Data Structures Polymorphism
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Taken from slides of Starting Out with C++ Early Objects Seventh Edition.
“is a”  Define a new class DerivedClass which extends BaseClass class BaseClass { // class contents } class DerivedClass : BaseClass { // class.
Lecture 9 Polymorphism Richard Gesick.
Inheritance Version 1.0. Topics Inheritance Constructors and Inheritance Hiding Methods and Variables Designing with Inheritance.
1 Chapter 10: Data Abstraction and Object Orientation Aaron Bloomfield CS 415 Fall 2005.
1 Inheritance We are modeling the operation of a transportation company that uses trains and trucks to transfer goods. A suitable class hierarchy for the.
Inheritance Version 1.1. Topics Inheritance Constructors and Inheritance Function Over-riding (Redefinition) The Stringstream class Shadowing Variables.
TCP1201 OOPDS Lecture 4 1. Learning Objectives  To understand upcasting & downcasting  To understand static polymorphism and dynamic polymorphism 
More on Hierarchies 1. When an object of a subclass is instantiated, is memory allocated for only the data members of the subclass or also for the members.
Parameters… Classes Cont Mrs. C. Furman October 13, 2008.
Genericity Ranga Rodrigo Based on Mark Priestley's Lectures.
1 Inheritance. 2 Why use inheritance?  The most important aspect of inheritance is that it expresses a relationship between the new class and the base.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes.
JAVA: An Introduction to Problem Solving & Programming, 5 th Ed. By Walter Savitch and Frank Carrano. ISBN © 2008 Pearson Education, Inc., Upper.
Chapter 3 Inheritance and Polymorphism Goals: 1.Superclasses and subclasses 2.Inheritance Hierarchy 3.Polymorphism 4.Type Compatibility 5.Abstract Classes.
Polymorphism and Virtual Functions. Topics Polymorphism Virtual Functions Pure Virtual Functions Abstract Base Classes Virtual Destructors V-Tables Run.
Copyright 2006 Oxford Consulting, Ltd1 February Polymorphism Polymorphism Polymorphism is a major strength of an object centered paradigm Same.
CSCI-383 Object-Oriented Programming & Design Lecture 18.
CS212: Object Oriented Analysis and Design Lecture 17: Virtual Functions.
OOP using C Abstract data types How to accomplish the task??? Requirements Details Input, output, process Specify each task in terms of input.
1 COSC2007 Data Structures II Chapter 9 Class Relationships.
CS-1030 Dr. Mark L. Hornick 1 Basic C++ State the difference between a function/class declaration and a function/class definition. Explain the purpose.
Polymorphism, Virtual Methods and Interfaces Version 1.1.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Inheritance and Class Hierarchies Chapter 3. Chapter Objectives  To understand inheritance and how it facilitates code reuse  To understand how Java.
Fall 2015CISC/CMPE320 - Prof. McLeod1 CISC/CMPE320 Assignment 3 is due Sunday, the 8 th at 7pm. Problems with assn 3? Discuss at your team meeting tonight.
Recap Introduction to Inheritance Inheritance in C++ IS-A Relationship Polymorphism in Inheritance Classes in Inheritance Visibility Rules Constructor.
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
Polymorphism and Virtual Functions One name many shapes behaviour Unit - 07.
Polymorphism Data Structures & OO Development I 1 Computer Science Dept Va Tech May 2006 ©2006 McQuain & Ribbens Definition polymorphismthe ability to.
Class Inheritance Inheritance as an is-a relationship Public derive one class from another Protected access Initializer lists in constructor Upcasting.
Polymorphism & Virtual Functions 1. Objectives 2  Polymorphism in C++  Pointers to derived classes  Important point on inheritance  Introduction to.
 Virtual Function Concepts: Abstract Classes & Pure Virtual Functions, Virtual Base classes, Friend functions, Static Functions, Assignment & copy initialization,
C++ How to Program, 7/e. © by Pearson Education, Inc. All Rights Reserved.2.
CSCI-383 Object-Oriented Programming & Design Lecture 17.
CPSC 252Inheritance II Page 1 Inheritance & Pointers Consider the following client code: const int MAXCLOCKS = 2; Clock* clockPtr[ MAXCLOCKS ]; clockPtr[0]
Class Inheritance Part II: Overriding and Polymorphism Corresponds with Chapter 10.
Design issues for Object-Oriented Languages
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
Virtual Function and Polymorphism
Polymorphism, Virtual Methods and Abstract Classes
Andy Wang Object Oriented Programming in C++ COP 3330
Object-Oriented Programming & Design Lecture 18 Martin van Bommel
Inheritance and Run time Polymorphism
CS212: Object Oriented Analysis and Design
Polymorphism & Virtual Functions
Polymorphism, Virtual Methods and Abstract Classes
Inheritance.
Designing for Inheritance
3.3 Abstract Classes, Assignment, and Casting in a Hierarchy
CISC/CMPE320 - Prof. McLeod
Today’s Objectives 10-Jul-2006 Announcements Quiz #3
Fundaments of Game Design
Static Binding Static binding chooses the function in the class of the base class pointer, ignoring any versions in the class of the object actually.
Presentation transcript:

Polymorphism, Virtual Methods and Abstract Classes

Topics Polymorphic Variables Collections of Object Pointers Virtual Functions Pure Virtual Functions Abstract Classes V-Tables Writing a ToString Function

Objectives At the completion of this module, students should be able to: Design classes that enable polymorphism * Properly use inheritance * Include virtual functions * Use pure virtual functions and abstract classes Correctly use polymorphism in a program * Store addresses of dynamically created objects in arrays or vectors of base class pointers Write and use a ToString function

Polymorphic Variables Consider the statement: Creature* cr1; The declared type of the pointer cr1 is Creature However, cr1 can potentially hold the address of an object of a different type. In particular, it can hold the address of an object of any class derived from Creature.

Pointers to Objects Programs that deal with lots of objects often use arrays of pointers to those objects. Recall that a pointer is a C++ data type that stores an address. For example, Creature* c1; Declares c1 to be a variable that contains the address of a creature object.

Dynamic Allocation Programs that deal with lots of objects often allocate the space for those objects dynamically. Remember that dynamically allocated objects are stored on the heap and we use the new keyword to allocate an object dynamically: Creature* c1 = new Creature(‘joe”, 123);

Arrays and Vectors of Object Pointers Programs that deal with lots of objects, where the number of objects the program has to deal with is unknown at compile time, will use an array or more often a vector to store pointers to dynamically allocated objects. vector aTeam;... aTeam.push_back( new Creature(‘joe”, 123) );

Inheritance and Pointers Because of the is-a relationship, an object of a derived class can always be treated as an object of the corresponding base class. In particular, you can always store the address of a derived class object in a base class pointer.

Creature* c1 = new Dwarf(“Egrew”, 600, 500, 2); The Dwarf object c1 c1 is a Creature pointer

So I could define a vector of Creature objects like this: const int TEAM = 3; Vector aTeam; aTeam.push_back( new Dwarf(“Bulgar”, 100, 300, 4) ); aTeam.push_back( new Elf(“Razel”, 200, 200, 12) ); aTeam.push_back( new Fairy(“Fiona”, 250, 150, 6, 3) );

Now what if I wrote a loop to compute the fight points for each of the creatures on my team: const int TEAM = 3; Vector aTeam; aTeam.push_back( new Dwarf(“Bulgar”, 100, 300, 4) ); aTeam.push_back( new Elf(“Razel”, 200, 200, 12) ); aTeam.push_back( new Fairy(“Fiona”, 250, 150, 6, 3) ); for (int i = 0; i < TEAM; i++) { cout getFightPoints( )); } Remember that getFightPoints( ) is implemented differently in each class

Since aTeam is an array of Creature class pointers, we know that this code will call the getFightPoints( ) method in the Creature class. Can we write this code so that it will call the correct getFightPoints method for the type of object being pointed to? The answer is YES!

Creature name strength hitpoints Dwarf Virtual Functions virtual int Creature::getFightPoints( ) { return strength; } int Dwarf::getFightPoints( ) { return strength + weapons; } * Make the getFightPoints function in the Creature class virtual.

const int TEAM = 3; Vector aTeam; aTeam.push_back( new Dwarf(“Bulgar”, 100, 300, 4) ); aTeam.push_back( new Elf(“Razel”, 200, 200, 12) ); aTeam.push_back( new Fairy(“Fiona”, 250, 150, 6, 3) ); for (int i = 0; i < TEAM; i++) { cout getFightPoints( )); } When i = 0 invoke The Dwarf’s getFightPoints( ) function When i = 1 invoke The Elf’s getFightPoints( ) function When i = 2 invoke The Fairy’s getFightPoints( ) function

Virtual Functions the keyword virtual in a base class function says that this function will use polymorphism. When we use a base class pointer to point to the object, and invoke the virtual function, the system will automatically find and execute the function defined in the correct derived class, not the one defined in the base class! Moreover, if we have many different derived classes, the system will find the correct function for the object that the reference points to. This is called late binding, or dynamic binding. virtual int Creature::GetDamage( ) { return strength; }

Rules for Polymorphism In the base class, the keyword virtual must precede any function that you want to call using polymorphism. In any derived class the signature must exactly match the signature of the function being over-ridden. If the signature is different, the compiler considers it to be a different function. The actual implementation of the function in the derived class will be different than that in the base class. The function is invoked through a base class pointer that contains the address of a derived class object.

Virtual Tables (V-Tables) how polymorphism works

For this discussion, assume that our Creature class has these functions: class Creature { … public: int getStrength( ); virtual void getFightPoints( ); virtual void toString ( ); };

V-Tables When the compiler encounters a class definition that contains a virtual method, it builds a v-table for that class. The v-table contains the addresses of all of the virtual methods for the class. class Creature { … public: int getStrength( ); virtual int getFightPoints( ); virtual string toString ( ); }; Creature’s v-table getFightPoints ( ) Creature::getFightPoints( ) toString( ) Creature::toString( ) getStrength( ) is not in the V-table because it is not virtual.

V-Tables class Dwarf : public Creature { … public: int getFightPoints( ); string toString(int); } When the compiler encounters a derived class definition that inherits from this base class, it makes a copy of the v-table from the base class for the derived class. Dwarf’s v-table getFightPoints ( ) Creature::getFightPoints( ) toString( ) Creature::toString( )

V-Tables Now, for any method in the derived class that over-rides a virtual method in the base class, the compiler sets the address for that method to the derived class method’s address. the signature of the toString( ) method does not match the one in the base class so no change is made to the v-table in this case. class Dwarf : public Creature { … public: int getFightPoints( ); string toString(int); } Dwarf’s v-table getFightPoints ( ) Dwarf::getFightPoints( ) toString( ) Creature::toString( )

Creature* cr1 = new Dwarf(“Dargon”, 200); member data The Dwarf object Now … create an object and save the address of the object in a variable that is a base class pointer. cr1

When the object of the derived class is created a pointer to the class’s v-table is added to the object. Creature* cr1 = new Dwarf(“Dargon”, 200); member data The Dwarf object cr1 Dwarf’s v-table getFightPoints ( ) Dwarf::getFightPoints( ) toString( ) Creature::toString( )

When the getFightPoints( ) method is invoked … cr1->getFightPoints ( ); 1.the pointer cr1 is used to find the object. 2. the pointer to the v-table is located in the object. 3. This pointer is used to locate the v-table 4. the getFightPoints function is located in the v-table and the corresponding address is used to invoke the correct method.. member data The Dwarf object cr1 Dwarf’s v-table getFightPoints ( ) Dwarf::getFightPoints( ) toString( ) Creature::toString( )

What happens now if you want to invoke the toString(int) function from the Dwarf class? the function toString(int) was not defined in the base class, and it is not virtual, so it is not in the v-table. You can’t do it unless you actually know that you have a Dwarf object – then you could cast the Pointer to a Dwarf pointer. You can test an object using run time type identification (RTTI) class Dwarf : public Creature { … public: int getFightPoints( ); string toString(int); } Dwarf’s v-table getFightPoints ( ) Dwarf::getFightPoints( ) toString( ) Creature::toString( )

Downcasting an Object Given the code Creature* cr1 = new Dwarf(“Samuel”, 150); You can’t invoke the toString(int) method directly, because cr1 is a Creature pointer and toString(int) is not a virtual method in the Creature class. cr1->toString(3);

Using Run Time Type Identification A dynamic cast verifies that a pointer can be safely converted to a pointer of a derived class. Dwarf* dptr = dynamic_cast (aTeam[0]);

If the dynamic cast is successful, the dynamic_cast operator returns the pointer, converted to the specified type. If the conversion cannot be done, a null pointer is returned. if (dptr ) // its not a null pointer cout toString( 5 ); } Dwarf* dptr = dynamic_cast (aTeam[0]);

Pure Virtual Functions In the previous example, we over-rode the getFightPoints( ) function in all of the classes derived from the Creature class. However, there was nothing in the structure of the code that forced us to do this. To force a derived class to override a virtual function in the base class, we must define that function as a pure virtual function.

The = 0 at the end of the function prototype tells the compiler that this is a pure virtual function. Pure virtual functions have no implementation code in the class. This forces every child class to implement the function. int getFightPoints( ) = 0;

Abstract Classes If a class contains at least one pure virtual function, the class becomes an abstract class. You cannot create an object from an abstract class. Abstract classes are truly an abstraction. They provide a contract for all derived classes, defining the public methods that a derived class must implement. If you can create an object from a class, we call that class a concrete class.

Abstract Classes If a class is abstract then it is impossible to create an object of that class. Why?

A very useful method to write for a class is the ToString Method. Most often we want the ToString method to return a textual representation of the class. The following slides illustrate how to write the toString method in the Creature classes. toString( )

The ostringstream class One of the important stream classes in C++ is the stringstream class. It operates much like the other stream classes in C++, but instead of generating any output, the ostringstream class generates a formatted string in memory. To retrieve the string, use the str( ) function that belongs to the ostingstream class. To use the stringstream class, #include

The toString( ) function in the Creature class: string Creature::toString( ) { ostringstream out; out << "My name is " << name << ".\n out << I have " << strength << " strength points"; return out.str( ); } Notice how the stream insertion operator works here just like it does with an I/O stream. create an ostringstream object get the string from the object

The toString( ) function in the Dwarf class: string Dwarf::toString( ) { ostringstream oss; oss << Creature::toString( ); oss << ", " << weapons << " weapons, and “; oss << getFightPoints( ) << " fight points."; return oss.str( ); } create the object call the base class toString function add Dwarf unique stuff

Upcasting vs. Downcasting Casting from a descendant type to an ancestor type is known as upcasting. It is always safe, since you are moving up the inheritance hierarchy. In our case, for example, we are always know that a dwarf is a creature. Casting from an ancestor type to a descendant type is called downcasting. In our case, we can’t guarantee that every creature is a dwarf, so downcasting a creature to a dwarf can be very dangerous, since we assume that information may be there that isn’t.

You can store the reference to a base class object in a derived class reference, but you must do an explicit cast to make this work. Dwarf* dw1; Creature* c1 = new Creature(“joe”, 400); Dw1 = (Dwarf)c1;

This is pretty dangerous and not often used, because the derived class reference thinks it is referencing a derived class object, but it really isn’t. This is referred to as the “slicing problem”. A Creature object dw1 base part there is no derived part. If you try to access member data in the derived part, you will get garbage!