0% found this document useful (0 votes)
59 views22 pages

Chapter 20-Virtual Functions and Polymorphism: 2000 Prentice Hall, Inc. All Rights Reserved

The document outlines a chapter on virtual functions and polymorphism. It discusses using virtual functions instead of switch statements to determine which function to call based on an object's type. Abstract base classes are introduced as classes that cannot be instantiated directly but provide interfaces to be implemented by derived concrete classes. Polymorphism allows objects of different derived classes to respond to the same function call differently by overriding virtual functions. Dynamic binding is explained as determining the correct function to call at runtime based on the object's actual type. The chapter also presents code examples of a class hierarchy using shapes to demonstrate these object-oriented programming concepts.

Uploaded by

DODI
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
59 views22 pages

Chapter 20-Virtual Functions and Polymorphism: 2000 Prentice Hall, Inc. All Rights Reserved

The document outlines a chapter on virtual functions and polymorphism. It discusses using virtual functions instead of switch statements to determine which function to call based on an object's type. Abstract base classes are introduced as classes that cannot be instantiated directly but provide interfaces to be implemented by derived concrete classes. Polymorphism allows objects of different derived classes to respond to the same function call differently by overriding virtual functions. Dynamic binding is explained as determining the correct function to call at runtime based on the object's actual type. The chapter also presents code examples of a class hierarchy using shapes to demonstrate these object-oriented programming concepts.

Uploaded by

DODI
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 22

Chapter 20- Virtual Functions and

Polymorphism
Outline
20.1 Introduction
20.2 Type Fields and switch Statements
20.3 Virtual Functions
20.4 Abstract Base Classes and Concrete Classes

20.5 Polymorphism
20.6 Case Study: A Payroll System Using
Polymorphism
20.7 New Classes and Dynamic Binding
20.8 Virtual Destructors
20.9 Case Study: Inheriting Interface and
Implementation
20.10 Polymorphism, virtual Functions and
Dynamic Binding “Under the Hood”

2000 Prentice Hall, Inc. All rights reserved.


20.1 Introduction

• virtual functions and polymorphism


– Design and implement systems that are more easily
extensible
– Programs written to generically process objects of all
existing classes in a hierarchy

2000 Prentice Hall, Inc. All rights reserved.


20.2 Type Fields and switch
Statements
• switch statement
– Take an action on a object based on its type
– A switch structure could determine which print function to
call based on which type in a hierarchy of shapes

• Problems with switch


– Programmer may forget to test all possible cases in a switch.
• Tracking this down can be time consuming and error prone
• virtual functions and polymorphic programming can eliminate the
need for switch

2000 Prentice Hall, Inc. All rights reserved.


20.3 Virtual Functions

• virtual functions
– Used instead of switch statements
– Declaration:
• Keyword virtual before function prototype in base class
virtual void draw() const;
– A base-class pointer to a derived class object will call the correct draw
function
– If a derived class does not define a virtual function it is inherited from the
base class

2000 Prentice Hall, Inc. All rights reserved.


20.3 Virtual Functions (II)

• ShapePtr->Draw();
– Compiler implements dynamic binding
– Function determined during execution time

• ShapeObject.Draw();
– Compiler implements static binding
– Function determined during compile-time

2000 Prentice Hall, Inc. All rights reserved.


20.4 Abstract and Concrete Classes

• Abstract classes
– Sole purpose is to provide a base class for other classes
– No objects of an abstract base class can be instantiated
• Too generic to define real objects, i.e.
TwoDimensionalShape
• Can have pointers and references
– Concrete classes - classes that can instantiate objects
• Provide specifics to make real objects , i.e. Square, Circle

2000 Prentice Hall, Inc. All rights reserved.


20.4 Abstract and Concrete Classes
(II)
• Making abstract classes
– Declare one or more virtual functions as “pure” by
initializing the function to zero

virtual double earnings() const = 0;


• Pure virtual function

2000 Prentice Hall, Inc. All rights reserved.


20.5 Polymorphism
• Polymorphism:
– Ability for objects of different classes to respond differently to the
same function call
– Base-class pointer (or reference) calls a virtual function
• C++ chooses the correct overridden function in object
– Suppose print not a virtual function

Employee e, *ePtr = &e;


HourlyWorker h, *hPtr = &h;
ePtr->print(); //call base-class print function
hPtr->print(); //call derived-class print function
ePtr=&h; //allowable implicit conversion
ePtr->print(); // still calls base-class print

2000 Prentice Hall, Inc. All rights reserved.


20.6 New Classes and Dynamic
Binding
• Dynamic binding (late binding )
– Object's type not needed when compiling virtual functions
– Accommodate new classes that have been added after compilation
– Important for ISV’s (Independent Software Vendors) who do not
wish to reveal source code to their customers

2000 Prentice Hall, Inc. All rights reserved.


20.7 Virtual Destructors

• Problem:
– If base-class pointer to a derived object is deleted, the base-
class destructor will act on the object

• Solution:
– Declare a virtual base-class destructor
– Now, the appropriate destructor will be called

2000 Prentice Hall, Inc. All rights reserved.


20.8 Case Study: Inheriting Interface
and Implementation

• Re-examine the Point, Circle, Cylinder


hierarchy
– Use the abstract base class Shape to head the hierarchy

2000 Prentice Hall, Inc. All rights reserved.


1 // Fig. 20.1: shape.h
2 // Definition of abstract base class Shape Outline
3 #ifndef SHAPE_H
4 #define SHAPE_H
5 1. Shape Definition
6 class Shape { (abstract base
7 public: class)
8 virtual double area() const { return 0.0; }
9 virtual double volume() const { return 0.0; } ---------------------
10
11 // pure virtual functions overridden in derived classes
12 virtual void printShapeName() const = 0; 1. Point Definition
13 virtual void print() const = 0; (derived class)
14 };
15
16 #endif
17 // Fig. 20.1: point1.h
18 // Definition of class Point
19 #ifndef POINT1_H
20 #define POINT1_H
21
22 #include <iostream>
23
24 using std::cout;
25
26 #include "shape.h"
27
28 class Point : public Shape {
29 public:
30 Point( int = 0, int = 0 ); // default constructor
31 void setPoint( int, int );
32 int getX() const { return x; }
33 int getY() const { return y; }
2000 Prentice Hall, Inc. All rights reserved.
34 virtual void printShapeName() const { cout << "Point: "; }
35 virtual void print() const; Outline
36 private:
37 int x, y; // x and y coordinates of Point
38 };
39 1. Point Definition
40 #endif (derived class)
41 // Fig. 20.1: point1.cpp
42 // Member function definitions for class Point 1.1 Function
43 #include "point1.h" Definitions
44
45 Point::Point( int a, int b ) { setPoint( a, b ); }
46
47 void Point::setPoint( int a, int b )
48 {
49 x = a;
50 y = b;
51 }
52
53 void Point::print() const
54 { cout << '[' << x << ", " << y << ']'; }

2000 Prentice Hall, Inc. All rights reserved.


55 // Fig. 20.1: circle1.h
56 // Definition of class Circle Outline
57 #ifndef CIRCLE1_H
58 #define CIRCLE1_H
59 #include "point1.h" 1. Circle Definition
60 (derived class)
61 class Circle : public Point {
62 public:
63 // default constructor
64 Circle( double r = 0.0, int x = 0, int y = 0 );
65
66 void setRadius( double );
67 double getRadius() const;
68 virtual double area() const;
69 virtual void printShapeName() const { cout << "Circle: "; }
70 virtual void print() const;
71 private:
72 double radius; // radius of Circle
73 };
74
75 #endif

2000 Prentice Hall, Inc. All rights reserved.


76 // Fig. 20.1: circle1.cpp
77 // Member function definitions for class Circle Outline
78 #include <iostream>
79
80 using std::cout;
81
1.1 Function
82 #include "circle1.h"
Definitions
83
84 Circle::Circle( double r, int a, int b )
85 : Point( a, b ) // call base-class constructor
86 { setRadius( r ); }
87
88 void Circle::setRadius( double r ) { radius = r > 0 ? r : 0; }
89
90 double Circle::getRadius() const { return radius; }
91
92 double Circle::area() const
93 { return 3.14159 * radius * radius; }
94
95 void Circle::print() const
96 {
97 Point::print();
98 cout << "; Radius = " << radius;
99 }

2000 Prentice Hall, Inc. All rights reserved.


100 // Fig. 20.1: cylindr1.h
101 // Definition of class Cylinder Outline
102 #ifndef CYLINDR1_H
103 #define CYLINDR1_H
104 #include "circle1.h"
1. Cylinder
105
Definition (derived
106 class Cylinder : public Circle {
class)
107 public:
108 // default constructor
109 Cylinder( double h = 0.0, double r = 0.0,
110 int x = 0, int y = 0 );
111
112 void setHeight( double );
113 double getHeight();
114 virtual double area() const;
115 virtual double volume() const;
116 virtual void printShapeName() const { cout << "Cylinder: "; }
117 virtual void print() const;
118 private:
119 double height; // height of Cylinder
120 };
121
122 #endif

2000 Prentice Hall, Inc. All rights reserved.


123 // Fig. 20.1: cylindr1.cpp
124 // Member and friend function definitions for class Cylinder Outline
125 #include <iostream>
126
127 using std::cout;
128 1.1 Function
129 #include "cylindr1.h" Definitions
130
131 Cylinder::Cylinder( double h, double r, int x, int y )
132 : Circle( r, x, y ) // call base-class constructor
133 { setHeight( h ); }
134
135 void Cylinder::setHeight( double h )
136 { height = h > 0 ? h : 0; }
137
138 double Cylinder::getHeight() { return height; }
139
140 double Cylinder::area() const
141 {
142 // surface area of Cylinder
143 return 2 * Circle::area() +
144 2 * 3.14159 * getRadius() * height;
145 }
146
147 double Cylinder::volume() const
148 { return Circle::area() * height; }
149
150 void Cylinder::print() const
151 {
152 Circle::print();
153 cout << "; Height = " << height;

154 } 2000 Prentice Hall, Inc. All rights reserved.
155 // Fig. 20.1: fig20_01.cpp
156 // Driver for shape, point, circle, cylinder hierarchy Outline
157 #include <iostream>
158
159 using std::cout;
160 using std::endl; Driver
161
162 #include <iomanip>
163 1. Load headers
164 using std::ios;
165 using std::setiosflags; 1.1 Function
166 using std::setprecision;
prototypes
167
168 #include "shape.h"
169 #include "point1.h" 1.2 Initialize
170 #include "circle1.h" objects
171 #include "cylindr1.h"
172
173 void virtualViaPointer( const Shape * );
174 void virtualViaReference( const Shape & );
175
176 int main()
177 {
178 cout << setiosflags( ios::fixed | ios::showpoint )
179 << setprecision( 2 );
180
181 Point point( 7, 11 ); // create a Point
182 Circle circle( 3.5, 22, 8 ); // create a Circle
183 Cylinder cylinder( 10, 3.3, 10, 10 ); // create a Cylinder
184
185 2000 Prentice Hall, Inc. All rights reserved.
point.printShapeName(); // static binding
186 point.print(); // static binding
187 cout << '\n'; Outline
188
189 circle.printShapeName(); // static binding
190 circle.print(); // static binding
191 cout << '\n';
2. Function calls
192
193 cylinder.printShapeName(); // static binding
194 cylinder.print(); // static binding
195 cout << "\n\n";
196
197 Shape *arrayOfShapes[ 3 ]; // array of base-class pointers
198
199 // aim arrayOfShapes[0] at derived-class Point object
200 arrayOfShapes[ 0 ] = &point;
201
202 // aim arrayOfShapes[1] at derived-class Circle object
203 arrayOfShapes[ 1 ] = &circle;
204
205 // aim arrayOfShapes[2] at derived-class Cylinder object
206 arrayOfShapes[ 2 ] = &cylinder;
207
208 // Loop through arrayOfShapes and call virtualViaPointer
209 // to print the shape name, attributes, area, and volume
210 // of each object using dynamic binding.
211 cout << "Virtual function calls made off "
212 << "base-class pointers\n";
213
214 for ( int i = 0; i < 3; i++ )
215 virtualViaPointer( arrayOfShapes[ i ] );
216
217 // Loop through arrayOfShapes and call virtualViaReference
218 // to print the shape name, attributes, area, and volume
219
2000 Prentice Hall, Inc. All rights reserved.
// of each object using dynamic binding.
220 cout << "Virtual function calls made off "
221 << "base-class references\n"; Outline
222
223 for ( int j = 0; j < 3; j++ )
224 virtualViaReference( *arrayOfShapes[ j ] );
2. Function calls
225
226 return 0;
227 }
228 3. Function
229 // Make virtual function calls off a base-class pointer Definitions
230 // using dynamic binding.
231 void virtualViaPointer( const Shape *baseClassPtr )
232 {
233 baseClassPtr->printShapeName();
234 baseClassPtr->print();
235 cout << "\nArea = " << baseClassPtr->area()
236 << "\nVolume = " << baseClassPtr->volume() << "\n\n";
237 }
238
239 // Make virtual function calls off a base-class reference
240 // using dynamic binding.
241 void virtualViaReference( const Shape &baseClassRef )
242 {
243 baseClassRef.printShapeName();
244 baseClassRef.print();
245 cout << "\nArea = " << baseClassRef.area()
246 << "\nVolume = " << baseClassRef.volume() << "\n\n";
247 
} 2000 Prentice Hall, Inc. All rights reserved.
Point: [7, 11]
Outline
Circle: [22, 8]; Radius = 3.50
Cylinder: [10, 10]; Radius = 3.30; Height = 10.00
Virtual function calls made off base-class pointers
Point: [7, 11] Program Output
Area = 0.00
Volume = 0.00
Circle: [22, 8]; Radius = 3.50
Area = 38.48
Volume = 0.00
Cylinder: [10, 10]; Radius = 3.30; Height = 10.00
Area = 275.77
Volume = 342.12
Virtual function calls made off base-class references
Point: [7, 11]
Area = 0.00
Volume = 0.00
Circle: [22, 8]; Radius = 3.50
Area = 38.48
Volume = 0.00
Cylinder: [10, 10]; Radius = 3.30; Height = 10.00
Area = 275.77
Volume = 342.12

2000 Prentice Hall, Inc. All rights reserved.


20.9 Polymorphism, virtual
Functions and Dynamic Binding
“Under the Hood”
• When to use polymorphism
– Polymorphism has a lot of overhead
– Polymorphism is not used in STL (Standard Template Library) to
optimize performance
• virtual function table (vtable)
– Every class with a virtual function has a vtable
– For every virtual function, vtable has a pointer to the proper
function
• If a derived class has the same function as a base class, then the
function pointer points to the base-class function
– Detailed explanation in Fig. 20.2

2000 Prentice Hall, Inc. All rights reserved.

You might also like