1 virtual functions and polymorphism chapter 10. 2 what you will learn what is polymorphism? how to...
TRANSCRIPT
1
Virtual Functions and Polymorphism
Chapter 10
2
What You Will Learn
• What is polymorphism?
• How to declare and use virtual functions for abstract classes
3Problem with Derived Classes
S h a pe c la ss h ie ra rchy
C ric le
R ig h t Tria n g le Iso sce le s Tria n g le
T ria n g le
S q ua re
R e c ta n g le
S ha pe
•Given the class hierarchy below
•Consider the existence of a draw function for each derived class
•Consider also an array of pointers to the base class (which can also point to various objects of the derived classes)
•How do you specify which print statement to be called when referencing the pointers
4
Solution 1: Type Casting
• For objects of other than base typeShape *shapePtr = (Shape*) item[i];Triangle *trianglePtr = (Triangle*) item[i+1];
• Poor solution– clumsy– must keep track of correct object type for
each item[i]
5
Solution 2: Variant Records
• Rewrite Shape class– private member is a variant record– consists of unions of structs for all possible derived
types– Display function would use switch stmt to
determine which struct should be used
• But -- contradicts OOP philosophy– object would not be autonomous -- knowing how to
manipulate its own data– when new derived class created, base class must
be adapted!
(See Definition)
6
Solution 3 : Type Fields and switch Statements• Could use switch statements to
specify which print function (according to which class) will be usedBut … Must remember to– make a type test– test all possible cases in a switch– modify switch statements when new
classes are derived
7
Real Solution
• Virtual functions• Polymorphic programming
8
Virtual functions• Declare the draw function in the
base class as a virtual function
• then override draw in each of the derived classes to draw the appropriate shape
virtual void draw ( ) const;virtual void draw ( ) const;
shapePtr->draw( ); /* correct draw( ) function will be used, no matter what shape is pointed to */
shapePtr->draw( ); /* correct draw( ) function will be used, no matter what shape is pointed to */
9
Virtual functions
• When virtual function called via pointer ->, the reference is resolved at run time– called dynamic binding
• When virtual function called by referencing a specific object (using dot operator) reference is resolved at compile time– called static binding
10
Abstract Base Classes• When we declare a class (as a type) we
usually intend to declare objects of that type– but … not always
• An abstract class is declared, not to be instantiated– usually are used in inheritance situation– thus called abstract base class– provides base class for intended derived
classes
11
Concrete Classes
• Class from which objects will actually be instantiated called a concreteconcrete class
• Example:
• AbstractAbstract Classes
Shape
TwoD_Shape ThreeD_Shape
Square Circle Triangle Cube Sphere Cylinder
Shape
TwoD_Shape ThreeD_Shape
Square Circle Triangle Cube Sphere Cylinder
12
Polymorphism
• Ability for objects – of different classes – related by inheritance
• Implemented with virtual functions• When request made thru base-class
pointer (or reference) to use a virtual function– C++ knows enough to choose the correct
overriden function
To respond differently to same member function call
13
Polymorphism
• A class is made abstract by declaring one or more of its virtual functions to be "pure"
• A pure virtual function is one with an initializer of =0 in its declaration
• If a class is derived from a class with a pure virtual function & no defn for that pure funct is provided– that class is also an abstract class– not possible to instantiate any objects
14
Case Study: Payroll System• Refer to figure 10.1 and audio of
Text CD• Demonstration of
– pure virtual functions– polymorphism– static binding– dynamic binding
15
New Classes & Dynamic Binding• New classes accommodated by
dynamic binding– also called late binding
• Type of an object not needed at compile time for a virtual function
• Type of virtual function determined at run time
• This makes adding new capabilities to systems easier to do
16
Dynamic Binding
• Enables a programmer to distribute software without revealing how something is done– distribute only header and .obj files of
base classes
• Another programmer who purchases the routines writes derived classes– dynamic (late or runtime) binding of
virtual functions are easily accommodated
17
Virtual Destructors
• Problems can occur when– using polymorphism– processing dynamically allocated objects– in a class hierarchy
• Consider the delete applied to base-class pointer to an object– base class destructor called– what if the pointer referenced a derived class
object -- other class members deleted??
18
Virtual Destructors
• Solution is to make all derived-class destructors to be virtual functions
• This causes the appropriate destructor to be called– the system knows which derived class
destructor applies– the successive destructors on up the
hierarchy are also called
19
Virtual Destructors
• If a class contains virtual functions– declare the base class destructor to be
virtual
• Then if an object in the hierarchy is destroyed explicitly with delete on a base-class pointer to a derived class object– destructor for appropriate class is called
20
Case Study Inheriting Interface & Implementation• Figure 10.2 -- access the audio for the text CD
• Note features of program– abstract base class Shape– virtual functions– some derived classes exclude area,
volume functions(if not needed)– calls to appropriate functions higher up in
the hierarchy– use of pointers, reference parameters
21Polymorphism, virtual Functions, Dynamic Binding "Under the Hood"• Dynamic binding requires calls to virtual
member functions be given to appropriate version of the function
• This is done "under the hood" with a function table called the vtable – contains pointers to each version of the virtual
functions
• System chooses virtual function defined for that class (or inherited from higher base class)
22Polymorphism, virtual Functions, Dynamic Binding "Under the Hood"
• Derived class is not required to override the virtual function in higher base class– it can use base class version of the function– vtable would reflect this
• Appropriate function pointer in vtable dereferenced at run time– does require some execution time overhead
• See Fig 10.3, pg 591, hear CD audio
23
Unions
• defn => a struct that holds only one of its members at a time during program execution
union Qty_type { int count; float linear_ft; long cu_in; };
Qty_type how_many;
union Qty_type { int count; float linear_ft; long cu_in; };
Qty_type how_many;
At run time, how_manycontains either
•an int
•a float
•a long . . .
But … never all three
Back