0% found this document useful (0 votes)
29 views

2003 Prentice Hall, Inc. All Rights Reserved

The document discusses object-oriented programming concepts like polymorphism and inheritance. It uses the example of a base Shape class with derived Circle, Point, and Cylinder classes. The key points are: 1) Polymorphism allows treating objects in the same class hierarchy as the base class using virtual functions and dynamic binding. 2) Inheritance creates "is-a" relationships where derived classes take on properties of the base class. 3) Base class pointers can point to derived class objects, invoking base class functions but with the derived class implementation.
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views

2003 Prentice Hall, Inc. All Rights Reserved

The document discusses object-oriented programming concepts like polymorphism and inheritance. It uses the example of a base Shape class with derived Circle, Point, and Cylinder classes. The key points are: 1) Polymorphism allows treating objects in the same class hierarchy as the base class using virtual functions and dynamic binding. 2) Inheritance creates "is-a" relationships where derived classes take on properties of the base class. 3) Base class pointers can point to derived class objects, invoking base class functions but with the derived class implementation.
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 92

1

Object-Oriented Programming:
Polymorphism
Outline
10.1 Introduction
10.2 Relationships Among Objects in an Inheritance Hierarchy
10.2.1 Invoking Base-Class Functions from Derived-Class
Objects
10.2.2 Aiming Derived-Class Pointers at Base-Class Objects
10.2.3 Derived-Class Member-Function Calls via Base-Class
Pointers
10.2.4 Virtual Functions
10.3 Polymorphism Examples
10.4 Type Fields and switch Structures
10.5 Abstract Classes
10.6 Case Study: Inheriting Interface and Implementation
10.7 Polymorphism, Virtual Functions and Dynamic Binding “Under the
Hood”
10.8 Virtual Destructors

 2003 Prentice Hall, Inc. All rights reserved.


2

10.1 Introduction

• Polymorphism
– “Program in the general”
– Treat objects in same class hierarchy as if all base class
– Virtual functions and dynamic binding
• Will explain how polymorphism works
– Makes programs extensible
• New classes added easily, can still be processed
• In our examples
– Use abstract base class Shape
• Defines common interface (functionality)
• Point, Circle and Cylinder inherit from Shape
– Class Employee for a natural example

 2003 Prentice Hall, Inc. All rights reserved.


3
10.2 Relationships Among Objects in an
Inheritance Hierarchy
• Previously (Section 9.4),
– Circle inherited from Point
– Manipulated Point and Circle objects using member
functions
• Now
– Invoke functions using base-class/derived-class pointers
– Introduce virtual functions
• Key concept
– Derived-class object can be treated as base-class object
• “is-a” relationship
• Base class is not a derived class object

 2003 Prentice Hall, Inc. All rights reserved.


4
10.2.1 Invoking Base-Class Functions from
Derived-Class Objects
• Aim pointers (base, derived) at objects (base,
derived)
– Base pointer aimed at base object
– Derived pointer aimed at derived object
• Both straightforward
– Base pointer aimed at derived object
• “is a” relationship
– Circle “is a” Point
• Will invoke base class functions
– Function call depends on the class of the pointer/handle
• Does not depend on object to which it points
• With virtual functions, this can be changed (more later)

 2003 Prentice Hall, Inc. All rights reserved.


5
1 // Fig. 10.1: point.h
2 // Point class definition represents an x-y coordinate pair.
Outline
3 #ifndef POINT_H
4 #define POINT_H
point.h (1 of 1)
5
6 class Point {
7
8 public:
9 Point( int = 0, int = 0 ); // default constructor
10
11 void setX( int ); // set x in coordinate pair
12 int getX() const; // return x from coordinate pair
13
Base class print function.
14 void setY( int ); // set y in coordinate pair
15 int getY() const; // return y from coordinate pair
16
17 void print() const; // output Point object
18
19 private:
20 int x; // x part of coordinate pair
21 int y; // y part of coordinate pair
22
23 }; // end class Point
24
25 #endif

 2003 Prentice Hall, Inc.


All rights reserved.
6
1 // Fig. 10.2: point.cpp
2 // Point class member-function definitions.
Outline
3 #include <iostream>
4
point.cpp (1 of 2)
5 using std::cout;
6
7 #include "point.h" // Point class definition
8
9 // default constructor
10 Point::Point( int xValue, int yValue )
11 : x( xValue ), y( yValue )
12 {
13 // empty body
14
15 } // end Point constructor
16
17 // set x in coordinate pair
18 void Point::setX( int xValue )
19 {
20 x = xValue; // no need for validation
21
22 } // end function setX
23

 2003 Prentice Hall, Inc.


All rights reserved.
7
24 // return x from coordinate pair
25 int Point::getX() const
Outline
26 {
27 return x;
point.cpp (2 of 2)
28
29 } // end function getX
30
31 // set y in coordinate pair
32 void Point::setY( int yValue )
33 {
34 y = yValue; // no need for validation
35
36 } // end function setY
37
38 // return y from coordinate pair
39 int Point::getY() const
40 {
41 return y;
42
43 } // end function getY
Output the x,y coordinates of
44 the Point.
45 // output Point object
46 void Point::print() const
47 {
48 cout << '[' << getX() << ", " << getY() << ']';
49
50 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
8
1 // Fig. 10.3: circle.h
2 // Circle class contains x-y coordinate pair and radius.
Outline
3 #ifndef CIRCLE_H
4 #define CIRCLE_H
circle.h (1 of 1)
5
6 #include "point.h" // Point class definition
7
8 class Circle : public Point {
9
10 public:
11
Circle inherits from
12 // default constructor Point, but redefines its
13 Circle( int = 0, int = 0, double = 0.0 ); function.
print
14
15 void setRadius( double ); // set radius
16 double getRadius() const; // return radius
17
18 double getDiameter() const; // return diameter
19 double getCircumference() const; // return circumference
20 double getArea() const; // return area
21
22 void print() const; // output Circle object
23
24 private:
25 double radius; // Circle's radius
26
27 }; // end class Circle
28
29 #endif  2003 Prentice Hall, Inc.
All rights reserved.
9
1 // Fig. 10.4: circle.cpp
2 // Circle class member-function definitions.
Outline
3 #include <iostream>
4
circle.cpp (1 of 3)
5 using std::cout;
6
7 #include "circle.h" // Circle class definition
8
9 // default constructor
10 Circle::Circle( int xValue, int yValue, double radiusValue )
11 : Point( xValue, yValue ) // call base-class constructor
12 {
13 setRadius( radiusValue );
14
15 } // end Circle constructor
16
17 // set radius
18 void Circle::setRadius( double radiusValue )
19 {
20 radius = ( radiusValue < 0.0 ? 0.0 : radiusValue );
21
22 } // end function setRadius
23

 2003 Prentice Hall, Inc.


All rights reserved.
10
24 // return radius
25 double Circle::getRadius() const
Outline
26 {
27 return radius;
circle.cpp (2 of 3)
28
29 } // end function getRadius
30
31 // calculate and return diameter
32 double Circle::getDiameter() const
33 {
34 return 2 * getRadius();
35
36 } // end function getDiameter
37
38 // calculate and return circumference
39 double Circle::getCircumference() const
40 {
41 return 3.14159 * getDiameter();
42
43 } // end function getCircumference
44
45 // calculate and return area
46 double Circle::getArea() const
47 {
48 return 3.14159 * getRadius() * getRadius();
49
50 } // end function getArea

 2003 Prentice Hall, Inc.


All rights reserved.
11
51
52 // output Circle object
Circle redefines its print Outline
53 void Circle::print() const function. It calls Point’s
54 { print function to output the
circle.cpp (3 of 3)
55 cout << "center = "; x,y coordinates of the center,
56 then prints the radius.
Point::print(); // invoke Point's print function
57 cout << "; radius = " << getRadius();
58
59 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
12
1 // Fig. 10.5: fig10_05.cpp
2 // Aiming base-class and derived-class pointers at base-class
Outline
3 // and derived-class objects, respectively.
4 #include <iostream>
fig10_05.cpp
5
(1 of 3)
6 using std::cout;
7 using std::endl;
8 using std::fixed;
9
10 #include <iomanip>
11
12 using std::setprecision;
13
14 #include "point.h" // Point class definition
15 #include "circle.h" // Circle class definition
16
17 int main()
18 {
19 Point point( 30, 50 );
20 Point *pointPtr = 0; // base-class pointer
21
22 Circle circle( 120, 89, 2.7 );
23 Circle *circlePtr = 0; // derived-class pointer
24

 2003 Prentice Hall, Inc.


All rights reserved.
13
25 Use objects and pointers to
// set floating-point numeric formatting
26 cout << fixed << setprecision( 2 ); call the print function. The
Outline
27 pointers and objects are of the
28 // output objects point and circle same class, so the proper fig10_05.cpp
29 cout << "Print point and circle objects:"
print function is called. (2 of 3)
30 << "\nPoint: ";
31 point.print(); // invokes Point's print
32 cout << "\nCircle: ";
33 circle.print(); // invokes Circle's print
34
35 // aim base-class pointer at base-class object and print
36 pointPtr = &point;
37 cout << "\n\nCalling print with base-class pointer to "
38 << "\nbase-class object invokes base-class print "
39 << "function:\n";
40 pointPtr->print(); // invokes Point's print
41
42 // aim derived-class pointer at derived-class object
43 // and print
44 circlePtr = &circle;
45 cout << "\n\nCalling print with derived-class pointer to "
46 << "\nderived-class object invokes derived-class "
47 << "print function:\n";
48 circlePtr->print(); // invokes Circle's print
49

 2003 Prentice Hall, Inc.


All rights reserved.
14
50 // aim base-class pointer at derived-class object and print
51 pointPtr = &circle;
Outline
52 cout << "\n\nCalling print with base-class pointer to "
53 << "derived-class object\ninvokes base-class print "
fig10_05.cpp
54 << "function on that derived-class object:\n";
(3 of 3)
55 pointPtr->print(); // invokes Point's print
56 cout << endl;
Aiming a base-class pointer at
57
58 return 0;
a derived object is allowed
59 (the Circle “is a” Point).
60 } // end main However, it calls Point’s
print function, determined by
the pointer type. virtual
functions allow us to change
this.

 2003 Prentice Hall, Inc.


All rights reserved.
15
Print point and circle objects:
Point: [30, 50]
Outline
Circle: center = [120, 89]; radius = 2.70
 
fig10_05.cpp
Calling print with base-class pointer to
output (1 of 1)
base-class object invokes base-class print function:
[30, 50]
 
Calling print with derived-class pointer to
derived-class object invokes derived-class print function:
center = [120, 89]; radius = 2.70
 
Calling print with base-class pointer to derived-class object
invokes base-class print function on that derived-class object:
[120, 89]

 2003 Prentice Hall, Inc.


All rights reserved.
16
10.2.2 Aiming Derived-Class Pointers at Base-
Class Objects
• Previous example
– Aimed base-class pointer at derived object
• Circle “is a” Point
• Aim a derived-class pointer at a base-class object
– Compiler error
• No “is a” relationship
• Point is not a Circle
• Circle has data/functions that Point does not
– setRadius (defined in Circle) not defined in Point
– Can cast base-object’s address to derived-class pointer
• Called downcasting (more in 10.9)
• Allows derived-class functionality

 2003 Prentice Hall, Inc. All rights reserved.


17
1 // Fig. 10.6: fig10_06.cpp
2 // Aiming a derived-class pointer at a base-class object.
Outline
3 #include "point.h" // Point class definition
4 #include "circle.h" // Circle class definition
fig10_06.cpp
5
(1 of 1)
6 int main()
7 {
8 Point point( 30, 50 ); fig10_06.cpp
9 Circle *circlePtr = 0; output (1 of 1)
10
11 // aim derived-class pointer at base-class object
12 circlePtr = &point; // Error: a Point is not a Circle
13
14 return 0;
15
16 } // end main

C:\cpphtp4\examples\ch10\fig10_06\Fig10_06.cpp(12) : error C2440:


'=' : cannot convert from 'class Point *' to 'class Circle *'
Types pointed to are unrelated; conversion requires
reinterpret_cast, C-style cast or function-style cast

 2003 Prentice Hall, Inc.


All rights reserved.
18
10.2.3 Derived-Class Member-Function Calls via
Base-Class Pointers
• Handle (pointer/reference)
– Base-pointer can aim at derived-object
• But can only call base-class functions
– Calling derived-class functions is a compiler error
• Functions not defined in base-class
• Common theme
– Data type of pointer/reference determines functions it can
call

 2003 Prentice Hall, Inc. All rights reserved.


19
1 // Fig. 10.7: fig10_07.cpp
2 // Attempting to invoke derived-class-only member functions
Outline
3 // through a base-class pointer.
4 #include "point.h" // Point class definition
fig10_07.cpp
5 #include "circle.h" // Circle class definition
(1 of 2)
6
7 int main()
8 {
9 Point *pointPtr = 0;
10 Circle circle( 120, 89, 2.7 );
11
12 // aim base-class pointer at derived-class object
13 pointPtr = &circle;
14
15 // invoke base-class member functions on derived-class
16 // object through base-class pointer
17 int x = pointPtr->getX();
18 int y = pointPtr->getY();
19 pointPtr->setX( 10 );
20 pointPtr->setY( 10 );
21 pointPtr->print();
22

 2003 Prentice Hall, Inc.


All rights reserved.
20
23 // attempt to invoke derived-class-only member functions
24 // on derived-class object through base-class pointer
Outline
25 double radius = pointPtr->getRadius();
26 pointPtr->setRadius( 33.33 );
fig10_07.cpp
27 double diameter = pointPtr->getDiameter();
(2 of 2)
28 double circumference = pointPtr->getCircumference();
29 double area = pointPtr->getArea();
30
31 return 0;
32
33 } // end main

These functions are only


defined in Circle.
However, pointPtr is of
class Point.

 2003 Prentice Hall, Inc.


All rights reserved.
21
C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(25) : error C2039:
'getRadius' : is not a member of 'Point' Outline
C:\cpphtp4\examples\ch10\fig10_07\point.h(6) :
see declaration of 'Point'
 
fig10_07.cpp
C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(26) : error C2039: output (1 of 1)
'setRadius' : is not a member of 'Point'
C:\cpphtp4\examples\ch10\fig10_07\point.h(6) :
see declaration of 'Point'
 
C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(27) : error C2039:
'getDiameter' : is not a member of 'Point'
C:\cpphtp4\examples\ch10\fig10_07\point.h(6) :
see declaration of 'Point'
 
C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(28) : error C2039:
'getCircumference' : is not a member of 'Point'
C:\cpphtp4\examples\ch10\fig10_07\point.h(6) :
see declaration of 'Point'
 
C:\cpphtp4\examples\ch10\fig10_07\fig10_07.cpp(29) : error C2039:
'getArea' : is not a member of 'Point'
C:\cpphtp4\examples\ch10\fig10_07\point.h(6) :
see declaration of 'Point'

 2003 Prentice Hall, Inc.


All rights reserved.
22

10.2.4 Virtual Functions

• Typically, pointer-class determines functions


• virtual functions
– Object (not pointer) determines function called
• Why useful?
– Suppose Circle, Triangle, Rectangle derived from
Shape
• Each has own draw function
– To draw any shape
• Have base class Shape pointer, call draw
• Program determines proper draw function at run time
(dynamically)
• Treat all shapes generically

 2003 Prentice Hall, Inc. All rights reserved.


23

10.2.4 Virtual Functions

• Declare draw as virtual in base class


– Override draw in each derived class
• Like redefining, but new function must have same signature
– If function declared virtual, can only be overridden
• virtual void draw() const;
• Once declared virtual, virtual in all derived classes
– Good practice to explicitly declare virtual
• Dynamic binding
– Choose proper function to call at run time
– Only occurs off pointer handles
• If function called from object, uses that object’s definition

 2003 Prentice Hall, Inc. All rights reserved.


24

10.2.4 Virtual Functions

• Example
– Redo Point, Circle example with virtual functions
– Base-class pointer to derived-class object
• Will call derived-class function

 2003 Prentice Hall, Inc. All rights reserved.


25
1 // Fig. 10.8: point.h
2 // Point class definition represents an x-y coordinate pair.
Outline
3 #ifndef POINT_H
4 #define POINT_H
point.h (1 of 1)
5
6 class Point {
7
8 public:
9 Point( int = 0, int = 0 ); // default constructor
10
11 void setX( int ); // set x in coordinate pair
12 int getX() const; // return x from coordinate pair
13
Print declared virtual. It
14 void setY( int ); // set y in coordinate pair
will be virtual in all
15 int getY() const; // return y from coordinate pair
16
derived classes.
17 virtual void print() const; // output Point object
18
19 private:
20 int x; // x part of coordinate pair
21 int y; // y part of coordinate pair
22
23 }; // end class Point
24
25 #endif

 2003 Prentice Hall, Inc.


All rights reserved.
26
1 // Fig. 10.9: circle.h
2 // Circle class contains x-y coordinate pair and radius.
Outline
3 #ifndef CIRCLE_H
4 #define CIRCLE_H
circle.h (1 of 1)
5
6 #include "point.h" // Point class definition
7
8 class Circle : public Point {
9
10 public:
11
12 // default constructor
13 Circle( int = 0, int = 0, double = 0.0 );
14
15 void setRadius( double ); // set radius
16 double getRadius() const; // return radius
17
18 double getDiameter() const; // return diameter
19 double getCircumference() const; // return circumference
20 double getArea() const; // return area
21
22 virtual void print() const; // output Circle object
23
24 private:
25 double radius; // Circle's radius
26
27 }; // end class Circle
28
29 #endif  2003 Prentice Hall, Inc.
All rights reserved.
27
1 // Fig. 10.10: fig10_10.cpp
2 // Introducing polymorphism, virtual functions and dynamic
Outline
3 // binding.
4 #include <iostream>
fig10_10.cpp
5
(1 of 3)
6 using std::cout;
7 using std::endl;
8 using std::fixed;
9
10 #include <iomanip>
11
12 using std::setprecision;
13
14 #include "point.h" // Point class definition
15 #include "circle.h" // Circle class definition
16
17 int main()
18 {
19 Point point( 30, 50 );
20 Point *pointPtr = 0;
21
22 Circle circle( 120, 89, 2.7 );
23 Circle *circlePtr = 0;
24

 2003 Prentice Hall, Inc.


All rights reserved.
28
25 // set floating-point numeric formatting
26 cout << fixed << setprecision( 2 );
Outline
27
28 // output objects point and circle using static binding
fig10_10.cpp
29 cout << "Invoking print function on point and circle "
(2 of 3)
30 << "\nobjects with static binding "
31 << "\n\nPoint: ";
32 point.print(); // static binding
33 cout << "\nCircle: ";
34 circle.print(); // static binding
35
36 // output objects point and circle using dynamic binding
37 cout << "\n\nInvoking print function on point and circle "
38 << "\nobjects with dynamic binding";
39
40 // aim base-class pointer at base-class object and print
41 pointPtr = &point;
42 cout << "\n\nCalling virtual function print with base-class"
43 << "\npointer to base-class object"
44 << "\ninvokes base-class print function:\n";
45 pointPtr->print();
46

 2003 Prentice Hall, Inc.


All rights reserved.
29
47 // aim derived-class pointer at derived-class
48 // object and print
Outline
49 circlePtr = &circle;
50 cout << "\n\nCalling virtual function print with "
fig10_10.cpp
51 << "\nderived-class pointer to derived-class object "
(3 of 3)
52 << "\ninvokes derived-class print function:\n";
53 circlePtr->print();
54
55 // aim base-class pointer at derived-class object and print
56 pointPtr = &circle;
57 cout << "\n\nCalling virtual function print with base-class"
58 << "\npointer to derived-class object "
59 << "\ninvokes derived-class print function:\n";
60 pointPtr->print(); // polymorphism: invokes circle's print
61 cout << endl;
62
63 return 0;
At run time, the program
64
determines that pointPtr is
65 } // end main
aiming at a Circle object,
and calls Circle’s print
function. This is an example
of polymorphism.

 2003 Prentice Hall, Inc.


All rights reserved.
30
Invoking print function on point and circle
objects with static binding
Outline
 
Point: [30, 50]
fig10_10.cpp
Circle: Center = [120, 89]; Radius = 2.70
output (1 of 1)
 
Invoking print function on point and circle
objects with dynamic binding
 
Calling virtual function print with base-class
pointer to base-class object
invokes base-class print function:
[30, 50]
 
Calling virtual function print with
derived-class pointer to derived-class object
invokes derived-class print function:
Center = [120, 89]; Radius = 2.70
 
Calling virtual function print with base-class
pointer to derived-class object
invokes derived-class print function:
Center = [120, 89]; Radius = 2.70

 2003 Prentice Hall, Inc.


All rights reserved.
31

10.2.4 Virtual Functions

• Polymorphism
– Same message, “print”, given to many objects
• All through a base pointer
– Message takes on “many forms”
• Summary
– Base-pointer to base-object, derived-pointer to derived
• Straightforward
– Base-pointer to derived object
• Can only call base-class functions
– Derived-pointer to base-object
• Compiler error
• Allowed if explicit cast made (more in section 10.9)

 2003 Prentice Hall, Inc. All rights reserved.


32

10.3 Polymorphism Examples

• Examples
– Suppose Rectangle derives from Quadrilateral
• Rectangle more specific Quadrilateral
• Any operation on Quadrilateral can be done on
Rectangle (i.e., perimeter, area)
• Suppose designing video game
– Base class SpaceObject
• Derived Martian, SpaceShip, LaserBeam
• Base function draw
– To refresh screen
• Screen manager has vector of base-class pointers to objects
• Send draw message to each object
• Same message has “many forms” of results

 2003 Prentice Hall, Inc. All rights reserved.


33

10.3 Polymorphism Examples

• Video game example, continued


– Easy to add class Mercurian
• Inherits from SpaceObject
• Provides own definition for draw
– Screen manager does not need to change code
• Calls draw regardless of object’s type
• Mercurian objects “plug right in”
• Polymorphism
– Command many objects without knowing type
– Extensible programs
• Add classes easily

 2003 Prentice Hall, Inc. All rights reserved.


34

10.4 Type Fields and switch Structures

• One way to determine object's class


– Give base class an attribute
• shapeType in class Shape
– Use switch to call proper print function
• Many problems
– May forget to test for case in switch
– If add/remove a class, must update switch structures
• Time consuming and error prone
• Better to use polymorphism
– Less branching logic, simpler programs, less debugging

 2003 Prentice Hall, Inc. All rights reserved.


35

10.5 Abstract Classes

• Abstract classes
– Sole purpose: to be a base class (called abstract base classes)
– Incomplete
• Derived classes fill in "missing pieces"
– Cannot make objects from abstract class
• However, can have pointers and references
• Concrete classes
– Can instantiate objects
– Implement all functions they define
– Provide specifics

 2003 Prentice Hall, Inc. All rights reserved.


36

10.5 Abstract Classes

• Abstract classes not required, but helpful


• To make a class abstract
– Need one or more "pure" virtual functions
• Declare function with initializer of 0
virtual void draw() const = 0;
– Regular virtual functions
• Have implementations, overriding is optional
– Pure virtual functions
• No implementation, must be overridden
– Abstract classes can have data and concrete functions
• Required to have one or more pure virtual functions

 2003 Prentice Hall, Inc. All rights reserved.


37

10.5 Abstract Classes

• Abstract base class pointers


– Useful for polymorphism
• Application example
– Abstract class Shape
• Defines draw as pure virtual function
– Circle, Triangle, Rectangle derived from Shape
• Each must implement draw
– Screen manager knows that each object can draw itself
• Iterators (more Chapter 21)
– Walk through elements in vector/array
– Use base-class pointer to send draw message to each

 2003 Prentice Hall, Inc. All rights reserved.


38
10.6 Case Study: Inheriting Interface and
Implementation
• Make abstract base class Shape
– Pure virtual functions (must be implemented)
• getName, print
• Default implementation does not make sense
– Virtual functions (may be redefined)
• getArea, getVolume
– Initially return 0.0
• If not redefined, uses base class definition
– Derive classes Point, Circle, Cylinder

 2003 Prentice Hall, Inc. All rights reserved.


39
10.6 Case Study: Inheriting Interface and
Implementation

getArea getVolume getName print

Shape 0.0 0.0 = 0 = 0

Point 0.0 0.0 "Point" [x,y]

r2 0.0 "Circle" center=[x,y];


Circle radius=r

center=[x,y];
Cylinder 2r +2rh
2
r h
2
"Cylinder" radius=r;
height=h

 2003 Prentice Hall, Inc. All rights reserved.


40
1 // Fig. 10.12: shape.h
2 // Shape abstract-base-class definition.
Outline
3 #ifndef SHAPE_H
4 #define SHAPE_H
shape.h (1 of 1)
5
6 #include <string> // C++ standard string class
7
8 using std::string;
9
10 class Shape {
11
Virtual and pure virtual
12 public: functions.
13
14 // virtual function that returns shape area
15 virtual double getArea() const;
16
17 // virtual function that returns shape volume
18 virtual double getVolume() const;
19
20 // pure virtual functions; overridden in derived classes
21 virtual string getName() const = 0; // return shape name
22 virtual void print() const = 0; // output shape
23
24 }; // end class Shape
25
26 #endif

 2003 Prentice Hall, Inc.


All rights reserved.
41
1 // Fig. 10.13: shape.cpp
2 // Shape class member-function definitions.
Outline
3 #include <iostream>
4
shape.cpp (1 of 1)
5 using std::cout;
6
7 #include "shape.h" // Shape class definition
8
9 // return area of shape; 0.0 by default
10 double getArea() const
11 {
12 return 0.0;
13
14 } // end function getArea
15
16 // return volume of shape; 0.0 by default
17 double getVolume() const
18 {
19 return 0.0;
20
21 } // end function getVolume

 2003 Prentice Hall, Inc.


All rights reserved.
42
1 // Fig. 10.14: point.h
2 // Point class definition represents an x-y coordinate pair.
Outline
3 #ifndef POINT_H
4 #define POINT_H
5
point.h (1 of 2)
6 #include "shape.h" // Shape class definition
7
8 class Point : public Shape {
9
10 public:
11 Point( int = 0, int = 0 ); // default constructor
12
Point only redefines
13 void setX( int ); // set x in coordinate pair
getName and print, since
14 int getX() const; // return x from coordinate pair
15
getArea and getVolume
16 void setY( int ); // set y in arepair
coordinate zero (it can use the default
17 int getY() const; // return y implementation).
from coordinate pair
18
19 // return name of shape (i.e., "Point" )
20 virtual string getName() const;
21
22 virtual void print() const; // output Point object
23

 2003 Prentice Hall, Inc.


All rights reserved.
43
24 private:
25 int x; // x part of coordinate pair
Outline
26 int y; // y part of coordinate pair
27
point.h (2 of 2)
28 }; // end class Point
29
30 #endif

 2003 Prentice Hall, Inc.


All rights reserved.
44
1 // Fig. 10.15: point.cpp
2 // Point class member-function definitions.
Outline
3 #include <iostream>
4
point.cpp (1 of 3)
5 using std::cout;
6
7 #include "point.h" // Point class definition
8
9 // default constructor
10 Point::Point( int xValue, int yValue )
11 : x( xValue ), y( yValue )
12 {
13 // empty body
14
15 } // end Point constructor
16
17 // set x in coordinate pair
18 void Point::setX( int xValue )
19 {
20 x = xValue; // no need for validation
21
22 } // end function setX
23

 2003 Prentice Hall, Inc.


All rights reserved.
45
24 // return x from coordinate pair
25 int Point::getX() const
Outline
26 {
27 return x;
point.cpp (2 of 3)
28
29 } // end function getX
30
31 // set y in coordinate pair
32 void Point::setY( int yValue )
33 {
34 y = yValue; // no need for validation
35
36 } // end function setY
37
38 // return y from coordinate pair
39 int Point::getY() const
40 {
41 return y;
42
43 } // end function getY
44

 2003 Prentice Hall, Inc.


All rights reserved.
46
45 // override pure virtual function getName: return name of Point
46 string Point::getName() const
Outline
47 {
48 return "Point";
point.cpp (3 of 3)
49
50 } // end function getName
51
52 // override pure virtual function print: output Point object
53 void Point::print() const
54 {
55 cout << '[' << getX() << ", " << getY() << ']';
56
57 } // end function print
Must override pure virtual
functions getName and
print.

 2003 Prentice Hall, Inc.


All rights reserved.
47
1 // Fig. 10.16: circle.h
2 // Circle class contains x-y coordinate pair and radius.
Outline
3 #ifndef CIRCLE_H
4 #define CIRCLE_H
circle.h (1 of 2)
5
6 #include "point.h" // Point class definition
7
8 class Circle : public Point {
9
10 public:
11
12 // default constructor
13 Circle( int = 0, int = 0, double = 0.0 );
14
15 void setRadius( double ); // set radius
16 double getRadius() const; // return radius
17
18 double getDiameter() const; // return diameter
19 double getCircumference() const; // return circumference
20 virtual double getArea() const; // return area
21
22 // return name of shape (i.e., "Circle")
23 virtual string getName() const;
24
25 virtual void print() const; // output Circle object

 2003 Prentice Hall, Inc.


All rights reserved.
48
26
27 private:
Outline
28 double radius; // Circle's radius
29
circle.h (2 of 2)
30 }; // end class Circle
31
32 #endif

 2003 Prentice Hall, Inc.


All rights reserved.
49
1 // Fig. 10.17: circle.cpp
2 // Circle class member-function definitions.
Outline
3 #include <iostream>
4
circle.cpp (1 of 3)
5 using std::cout;
6
7 #include "circle.h" // Circle class definition
8
9 // default constructor
10 Circle::Circle( int xValue, int yValue, double radiusValue )
11 : Point( xValue, yValue ) // call base-class constructor
12 {
13 setRadius( radiusValue );
14
15 } // end Circle constructor
16
17 // set radius
18 void Circle::setRadius( double radiusValue )
19 {
20 radius = ( radiusValue < 0.0 ? 0.0 : radiusValue );
21
22 } // end function setRadius
23

 2003 Prentice Hall, Inc.


All rights reserved.
50
24 // return radius
25 double Circle::getRadius() const
Outline
26 {
27 return radius;
circle.cpp (2 of 3)
28
29 } // end function getRadius
30
31 // calculate and return diameter
32 double Circle::getDiameter() const
33 {
34 return 2 * getRadius();
35
36 } // end function getDiameter
37
38 // calculate and return circumference
39 double Circle::getCircumference() const
40 {
41 return 3.14159 * getDiameter();
42
43 } // end function getCircumference
44

 2003 Prentice Hall, Inc.


All rights reserved.
51
45 // override virtual function getArea: return area of Circle
46 double Circle::getArea() const
Outline
47 {
48 return 3.14159 * getRadius() * getRadius();
circle.cpp (3 of 3)
49
50 } // end function getArea
51
52 Override
// override virutual function getName: return name of because
getArea Circle it
53 string Circle::getName() const now applies to Circle.
54 {
55 return "Circle";
56
57 } // end function getName
58
59 // override virtual function print: output Circle object
60 void Circle::print() const
61 {
62 cout << "center is ";
63 Point::print(); // invoke Point's print function
64 cout << "; radius is " << getRadius();
65
66 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
52
1 // Fig. 10.18: cylinder.h
2 // Cylinder class inherits from class Circle.
Outline
3 #ifndef CYLINDER_H
4 #define CYLINDER_H
cylinder.h (1 of 2)
5
6 #include "circle.h" // Circle class definition
7
8 class Cylinder : public Circle {
9
10 public:
11
12 // default constructor
13 Cylinder( int = 0, int = 0, double = 0.0, double = 0.0 );
14
15 void setHeight( double ); // set Cylinder's height
16 double getHeight() const; // return Cylinder's height
17
18 virtual double getArea() const; // return Cylinder's area
19 virtual double getVolume() const; // return Cylinder's volume
20

 2003 Prentice Hall, Inc.


All rights reserved.
53
21 // return name of shape (i.e., "Cylinder" )
22 virtual string getName() const;
Outline
23
24 virtual void print() const; // output Cylinder
cylinder.h (2 of 2)
25
26 private:
27 double height; // Cylinder's height
28
29 }; // end class Cylinder
30
31 #endif

 2003 Prentice Hall, Inc.


All rights reserved.
54
1 // Fig. 10.19: cylinder.cpp
2 // Cylinder class inherits from class Circle.
Outline
3 #include <iostream>
4
cylinder.cpp
5 using std::cout;
(1 of 3)
6
7 #include "cylinder.h" // Cylinder class definition
8
9 // default constructor
10 Cylinder::Cylinder( int xValue, int yValue, double radiusValue,
11 double heightValue )
12 : Circle( xValue, yValue, radiusValue )
13 {
14 setHeight( heightValue );
15
16 } // end Cylinder constructor
17
18 // set Cylinder's height
19 void Cylinder::setHeight( double heightValue )
20 {
21 height = ( heightValue < 0.0 ? 0.0 : heightValue );
22
23 } // end function setHeight

 2003 Prentice Hall, Inc.


All rights reserved.
55
24
25 // get Cylinder's height
Outline
26 double Cylinder::getHeight() const
27 {
cylinder.cpp
28 return height;
(2 of 3)
29
30 } // end function getHeight
31
32 // override virtual function getArea: return Cylinder area
33 double Cylinder::getArea() const
34 {
35 return 2 * Circle::getArea() + // code reuse
36 getCircumference() * getHeight();
37
38 } // end function getArea
39
40 // override virtual function getVolume: return Cylinder volume
41 double Cylinder::getVolume() const
42 {
43 return Circle::getArea() * getHeight(); // code reuse
44
45 } // end function getVolume
46

 2003 Prentice Hall, Inc.


All rights reserved.
56
47 // override virtual function getName: return name of Cylinder
48 string Cylinder::getName() const
Outline
49 {
50 return "Cylinder";
cylinder.cpp
51
(3 of 3)
52 } // end function getName
53
54 // output Cylinder object
55 void Cylinder::print() const
56 {
57 Circle::print(); // code reuse
58 cout << "; height is " << getHeight();
59
60 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
57
1 // Fig. 10.20: fig10_20.cpp
2 // Driver for shape, point, circle, cylinder hierarchy.
Outline
3 #include <iostream>
4
fig10_20.cpp
5 using std::cout;
(1 of 5)
6 using std::endl;
7 using std::fixed;
8
9 #include <iomanip>
10
11 using std::setprecision;
12
13 #include <vector>
14
15 using std::vector;
16
17 #include "shape.h" // Shape class definition
18 #include "point.h" // Point class definition
19 #include "circle.h" // Circle class definition
20 #include "cylinder.h" // Cylinder class definition
21
22 void virtualViaPointer( const Shape * );
23 void virtualViaReference( const Shape & );
24

 2003 Prentice Hall, Inc.


All rights reserved.
58
25 int main()
26 {
Outline
27 // set floating-point number format
28 cout << fixed << setprecision( 2 );
fig10_20.cpp
29
(2 of 5)
30 Point point( 7, 11 ); // create a Point
31 Circle circle( 22, 8, 3.5 ); // create a Circle
32 Cylinder cylinder( 10, 10, 3.3, 10 ); // create a Cylinder
33
34 cout << point.getName() << ": "; // static binding
35 point.print(); // static binding
36 cout << '\n';
37
38 cout << circle.getName() << ": "; // static binding
39 circle.print(); // static binding
40 cout << '\n';
41
42 cout << cylinder.getName() << ": "; // static binding
43 cylinder.print(); // static binding
44 cout << "\n\n";
45

 2003 Prentice Hall, Inc.


All rights reserved.
59
46 // create vector of three base-class pointers
47 vector< Shape * > shapeVector( 3 );
Outline
48 Create a vector of generic
49 // aim shapeVector[0] at derived-class Shape
Point pointers, and aim them at
object
fig10_20.cpp
50 shapeVector[ 0 ] = &point; various objects.
(3 of 5)
51
52 Function
// aim shapeVector[1] at derived-class Circle object
53 shapeVector[ 1 ] = &circle; virtualViaPointer calls
54 the virtual functions (print,
55 // aim shapeVector[2] at derived-class Cylinder object
getName, etc.) using the base-
56 shapeVector[ 2 ] = &cylinder;
class pointers.
57
58 // loop through shapeVector and call virtualViaPointer
59 The and
// to print the shape name, attributes, area typesvolume
are dynamically bound
60 // of each object using dynamic binding at run-time.
61 cout << "\nVirtual function calls made off "
62 << "base-class pointers:\n\n";
63
64 for ( int i = 0; i < shapeVector.size(); i++ )
65 virtualViaPointer( shapeVector[ i ] );
66

 2003 Prentice Hall, Inc.


All rights reserved.
60
67 // loop through shapeVector and call virtualViaReference
68 // to print the shape name, attributes, area and volume
Outline
69 // of each object using dynamic binding
70 cout << "\nVirtual function calls made off "
Use references instead of fig10_20.cpp
71 << "base-class references:\n\n";
pointers, for the same effect. (4 of 5)
72
73 for ( int j = 0; j < shapeVector.size(); j++ )
74 virtualViaReference( *shapeVector[ j ] );
75
76 return 0;
77
78 } // end main
79
80 // make virtual function calls off a base-class pointer
Call virtual functions; the
81 // using dynamic binding
82
proper class function will be
void virtualViaPointer( const Shape *baseClassPtr )
83 { called at run-time.
84 cout << baseClassPtr->getName() << ": ";
85
86 baseClassPtr->print();
87
88 cout << "\narea is " << baseClassPtr->getArea()
89 << "\nvolume is " << baseClassPtr->getVolume()
90 << "\n\n";
91
92 } // end function virtualViaPointer
93

 2003 Prentice Hall, Inc.


All rights reserved.
61
94 // make virtual function calls off a base-class reference
95 // using dynamic binding
Outline
96 void virtualViaReference( const Shape &baseClassRef )
97 {
fig10_20.cpp
98 cout << baseClassRef.getName() << ": ";
(5 of 5)
99
100 baseClassRef.print();
101
102 cout << "\narea is " << baseClassRef.getArea()
103 << "\nvolume is " << baseClassRef.getVolume() << "\n\n";
104
105 } // end function virtualViaReference

 2003 Prentice Hall, Inc.


All rights reserved.
62
Point: [7, 11]
Circle: center is [22, 8]; radius is 3.50
Outline
Cylinder: center is [10, 10]; radius is 3.30; height is 10.00
 
fig10_20.cpp
 
output (1 of 2)
Virtual function calls made off base-class pointers:
 
Point: [7, 11]
area is 0.00
volume is 0.00
 
Circle: center is [22, 8]; radius is 3.50
area is 38.48
volume is 0.00
 
Cylinder: center is [10, 10]; radius is 3.30; height is 10.00
area is 275.77
volume is 342.12
 
 
 

 2003 Prentice Hall, Inc.


All rights reserved.
63
Virtual function calls made off base-class references:
 
Outline
Point: [7, 11]
area is 0.00
fig10_20.cpp
volume is 0.00
output (2 of 2)
Circle: center is [22, 8]; radius is 3.50
area is 38.48
volume is 0.00
 
Cylinder: center is [10, 10]; radius is 3.30; height is 10.00
area is 275.77
volume is 342.12

 2003 Prentice Hall, Inc.


All rights reserved.
64
10.7 Polymorphism, Virtual Functions and
Dynamic Binding “Under the Hood”
• Polymorphism has overhead
– 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 pointer to the
proper function
– If derived class has same function as base class
• Function pointer aims at base-class function
– Detailed explanation in Fig. 10.21

 2003 Prentice Hall, Inc. All rights reserved.


65

10.8 Virtual Destructors

• Base class pointer to derived object


– If destroyed using delete, behavior unspecified
• Simple fix
– Declare base-class destructor virtual
• Makes derived-class destructors virtual
– Now, when delete used appropriate destructor called
• When derived-class object destroyed
– Derived-class destructor executes first
– Base-class destructor executes afterwards
• Constructors cannot be virtual

 2003 Prentice Hall, Inc. All rights reserved.


66
10.9 Case Study: Payroll System Using
Polymorphism
• Create a payroll program
– Use virtual functions and polymorphism
• Problem statement
– 4 types of employees, paid weekly
• Salaried (fixed salary, no matter the hours)
• Hourly (overtime [>40 hours] pays time and a half)
• Commission (paid percentage of sales)
• Base-plus-commission (base salary + percentage of sales)
– Boss wants to raise pay by 10%

 2003 Prentice Hall, Inc. All rights reserved.


67
10.9 Case Study: Payroll System Using
Polymorphism
• Base class Employee
– Pure virtual function earnings (returns pay)
• Pure virtual because need to know employee type
• Cannot calculate for generic employee
– Other classes derive from Employee

Employee

SalariedEmployee CommissionEmployee HourlyEmployee

BasePlusCommissionEmployee

 2003 Prentice Hall, Inc. All rights reserved.


68
10.9 Case Study: Payroll System Using
Polymorphism
• Downcasting
– dynamic_cast operator
• Determine object's type at runtime
• Returns 0 if not of proper type (cannot be cast)
NewClass *ptr = dynamic_cast < NewClass *> objectPtr;

• Keyword typeid
– Header <typeinfo>
– Usage: typeid(object)
• Returns type_info object
• Has information about type of operand, including name
• typeid(object).name()

 2003 Prentice Hall, Inc. All rights reserved.


69
1 // Fig. 10.23: employee.h
2 // Employee abstract base class.
Outline
3 #ifndef EMPLOYEE_H
4 #define EMPLOYEE_H
employee.h (1 of 2)
5
6 #include <string> // C++ standard string class
7
8 using std::string;
9
10 class Employee {
11
12 public:
13 Employee( const string &, const string &, const string & );
14
15 void setFirstName( const string & );
16 string getFirstName() const;
17
18 void setLastName( const string & );
19 string getLastName() const;
20
21 void setSocialSecurityNumber( const string & );
22 string getSocialSecurityNumber() const;
23

 2003 Prentice Hall, Inc.


All rights reserved.
70
24 // pure virtual function makes Employee abstract base class
25 virtual double earnings() const = 0; // pure virtual
Outline
26 virtual void print() const; // virtual
27
employee.h (2 of 2)
28 private:
29 string firstName;
30 string lastName;
31 string socialSecurityNumber;
32
33 }; // end class Employee
34
35 #endif // EMPLOYEE_H

 2003 Prentice Hall, Inc.


All rights reserved.
71
1 // Fig. 10.24: employee.cpp
2 // Abstract-base-class Employee member-function definitions.
Outline
3 // Note: No definitions are given for pure virtual functions.
4 #include <iostream>
employee.cpp
5
(1 of 3)
6 using std::cout;
7 using std::endl;
8
9 #include "employee.h" // Employee class definition
10
11 // constructor
12 Employee::Employee( const string &first, const string &last,
13 const string &SSN )
14 : firstName( first ),
15 lastName( last ),
16 socialSecurityNumber( SSN )
17 {
18 // empty body
19
20 } // end Employee constructor
21

 2003 Prentice Hall, Inc.


All rights reserved.
72
22 // return first name
23 string Employee::getFirstName() const
Outline
24 {
25 return firstName;
employee.cpp
26
(2 of 3)
27 } // end function getFirstName
28
29 // return last name
30 string Employee::getLastName() const
31 {
32 return lastName;
33
34 } // end function getLastName
35
36 // return social security number
37 string Employee::getSocialSecurityNumber() const
38 {
39 return socialSecurityNumber;
40
41 } // end function getSocialSecurityNumber
42
43 // set first name
44 void Employee::setFirstName( const string &first )
45 {
46 firstName = first;
47
48 } // end function setFirstName
49
 2003 Prentice Hall, Inc.
All rights reserved.
73
50 // set last name
51 void Employee::setLastName( const string &last )
Outline
52 {
53 lastName = last;
employee.cpp
54
(3 of 3)
55 } // end function setLastName
56
57 // set social security number
58 void Employee::setSocialSecurityNumber( const string &number )
59 {
60 socialSecurityNumber = number; // should validate
61
62 Default
} // end function setSocialSecurityNumber implementation for
63 virtual function print.
64 // print Employee's information
65 void Employee::print() const
66 {
67 cout << getFirstName() << ' ' << getLastName()
68 << "\nsocial security number: "
69 << getSocialSecurityNumber() << endl;
70
71 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
74
1 // Fig. 10.25: salaried.h
2 // SalariedEmployee class derived from Employee.
Outline
3 #ifndef SALARIED_H
4 #define SALARIED_H
salaried.h (1 of 1)
5
6 #include "employee.h" // Employee class definition
7
8 class SalariedEmployee : public Employee {
9
10 public:
New functions for the
11 SalariedEmployee
SalariedEmployee( const string &, const string &, class.
12 const string &, double = 0.0 );
13 earnings must be
14 void setWeeklySalary( double ); overridden. print is
15 double getWeeklySalary() const; overridden to specify that this
16 is a salaried employee.
17 virtual double earnings() const;
18 virtual void print() const; // "salaried employee: "
19
20 private:
21 double weeklySalary;
22
23 }; // end class SalariedEmployee
24
25 #endif // SALARIED_H

 2003 Prentice Hall, Inc.


All rights reserved.
75
1 // Fig. 10.26: salaried.cpp
2 // SalariedEmployee class member-function definitions.
Outline
3 #include <iostream>
4
salaried.cpp
5 using std::cout;
(1 of 2)
6
7 #include "salaried.h" // SalariedEmployee class definition
8
9 // SalariedEmployee constructor
10
Use base class constructor
SalariedEmployee::SalariedEmployee( const string &first,
for
11 const string &last, const string basic fields.
&socialSecurityNumber,
12 double salary )
13 : Employee( first, last, socialSecurityNumber )
14 {
15 setWeeklySalary( salary );
16
17 } // end SalariedEmployee constructor
18
19 // set salaried employee's salary
20 void SalariedEmployee::setWeeklySalary( double salary )
21 {
22 weeklySalary = salary < 0.0 ? 0.0 : salary;
23
24 } // end function setWeeklySalary
25

 2003 Prentice Hall, Inc.


All rights reserved.
76
26 // calculate salaried employee's pay
27 double SalariedEmployee::earnings() const
Outline
28 {
29 return getWeeklySalary();
salaried.cpp
30
Must implement pure virtual (2 of 2)
31 } // end function earnings
32 functions.
33 // return salaried employee's salary
34 double SalariedEmployee::getWeeklySalary() const
35 {
36 return weeklySalary;
37
38 } // end function getWeeklySalary
39
40 // print salaried employee's name
41 void SalariedEmployee::print() const
42 {
43 cout << "\nsalaried employee: ";
44 Employee::print(); // code reuse
45
46 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
77
1 // Fig. 10.27: hourly.h
2 // HourlyEmployee class definition.
Outline
3 #ifndef HOURLY_H
4 #define HOURLY_H
hourly.h (1 of 1)
5
6 #include "employee.h" // Employee class definition
7
8 class HourlyEmployee : public Employee {
9
10 public:
11 HourlyEmployee( const string &, const string &,
12 const string &, double = 0.0, double = 0.0 );
13
14 void setWage( double );
15 double getWage() const;
16
17 void setHours( double );
18 double getHours() const;
19
20 virtual double earnings() const;
21 virtual void print() const;
22
23 private:
24 double wage; // wage per hour
25 double hours; // hours worked for week
26
27 }; // end class HourlyEmployee
28
29 #endif // HOURLY_H  2003 Prentice Hall, Inc.
All rights reserved.
78
1 // Fig. 10.28: hourly.cpp
2 // HourlyEmployee class member-function definitions.
Outline
3 #include <iostream>
4
hourly.cpp (1 of 3)
5 using std::cout;
6
7 #include "hourly.h"
8
9 // constructor for class HourlyEmployee
10 HourlyEmployee::HourlyEmployee( const string &first,
11 const string &last, const string &socialSecurityNumber,
12 double hourlyWage, double hoursWorked )
13 : Employee( first, last, socialSecurityNumber )
14 {
15 setWage( hourlyWage );
16 setHours( hoursWorked );
17
18 } // end HourlyEmployee constructor
19
20 // set hourly employee's wage
21 void HourlyEmployee::setWage( double wageAmount )
22 {
23 wage = wageAmount < 0.0 ? 0.0 : wageAmount;
24
25 } // end function setWage

 2003 Prentice Hall, Inc.


All rights reserved.
79
26
27 // set hourly employee's hours worked
Outline
28 void HourlyEmployee::setHours( double hoursWorked )
29 {
hourly.cpp (2 of 3)
30 hours = ( hoursWorked >= 0.0 && hoursWorked <= 168.0 ) ?
31 hoursWorked : 0.0;
32
33 } // end function setHours
34
35 // return hours worked
36 double HourlyEmployee::getHours() const
37 {
38 return hours;
39
40 } // end function getHours
41
42 // return wage
43 double HourlyEmployee::getWage() const
44 {
45 return wage;
46
47 } // end function getWage
48

 2003 Prentice Hall, Inc.


All rights reserved.
80
49 // get hourly employee's pay
50 double HourlyEmployee::earnings() const
Outline
51 {
52 if ( hours <= 40 ) // no overtime
hourly.cpp (3 of 3)
53 return wage * hours;
54 else // overtime is paid at wage * 1.5
55 return 40 * wage + ( hours - 40 ) * wage * 1.5;
56
57 } // end function earnings
58
59 // print hourly employee's information
60 void HourlyEmployee::print() const
61 {
62 cout << "\nhourly employee: ";
63 Employee::print(); // code reuse
64
65 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
81
1 // Fig. 10.29: commission.h
2 // CommissionEmployee class derived from Employee.
Outline
3 #ifndef COMMISSION_H
4 #define COMMISSION_H
commission.h
5
(1 of 1)
6 #include "employee.h" // Employee class definition
7
8 class CommissionEmployee : public Employee {
9
10 public:
11
Must set rate and sales.
CommissionEmployee( const string &, const string &,
12 const string &, double = 0.0, double = 0.0 );
13
14 void setCommissionRate( double );
15 double getCommissionRate() const;
16
17 void setGrossSales( double );
18 double getGrossSales() const;
19
20 virtual double earnings() const;
21 virtual void print() const;
22
23 private:
24 double grossSales; // gross weekly sales
25 double commissionRate; // commission percentage
26
27 }; // end class CommissionEmployee
28
29 #endif // COMMISSION_H  2003 Prentice Hall, Inc.
All rights reserved.
82
1 // Fig. 10.30: commission.cpp
2 // CommissionEmployee class member-function definitions.
Outline
3 #include <iostream>
4
commission.cpp
5 using std::cout;
(1 of 3)
6
7 #include "commission.h" // Commission class
8
9 // CommissionEmployee constructor
10 CommissionEmployee::CommissionEmployee( const string &first,
11 const string &last, const string &socialSecurityNumber,
12 double grossWeeklySales, double percent )
13 : Employee( first, last, socialSecurityNumber )
14 {
15 setGrossSales( grossWeeklySales );
16 setCommissionRate( percent );
17
18 } // end CommissionEmployee constructor
19
20 // return commission employee's rate
21 double CommissionEmployee::getCommissionRate() const
22 {
23 return commissionRate;
24
25 } // end function getCommissionRate

 2003 Prentice Hall, Inc.


All rights reserved.
83
26
27 // return commission employee's gross sales amount
Outline
28 double CommissionEmployee::getGrossSales() const
29 {
commission.cpp
30 return grossSales;
(2 of 3)
31
32 } // end function getGrossSales
33
34 // set commission employee's weekly base salary
35 void CommissionEmployee::setGrossSales( double sales )
36 {
37 grossSales = sales < 0.0 ? 0.0 : sales;
38
39 } // end function setGrossSales
40
41 // set commission employee's commission
42 void CommissionEmployee::setCommissionRate( double rate )
43 {
44 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
45
46 } // end function setCommissionRate
47

 2003 Prentice Hall, Inc.


All rights reserved.
84
48 // calculate commission employee's earnings
49 double CommissionEmployee::earnings() const
Outline
50 {
51 return getCommissionRate() * getGrossSales();
commission.cpp
52
(3 of 3)
53 } // end function earnings
54
55 // print commission employee's name
56 void CommissionEmployee::print() const
57 {
58 cout << "\ncommission employee: ";
59 Employee::print(); // code reuse
60
61 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
85
1 // Fig. 10.31: baseplus.h
2 Inherits from
// BasePlusCommissionEmployee class derived from Employee.
Outline
3 #ifndef BASEPLUS_H CommissionEmployee
4 #define BASEPLUS_H (and from Employee
baseplus.h (1 of 1)
5 indirectly).
6 #include "commission.h" // Employee class definition
7
8 class BasePlusCommissionEmployee : public CommissionEmployee {
9
10 public:
11 BasePlusCommissionEmployee( const string &, const string &,
12 const string &, double = 0.0, double = 0.0, double = 0.0 );
13
14 void setBaseSalary( double );
15 double getBaseSalary() const;
16
17 virtual double earnings() const;
18 virtual void print() const;
19
20 private:
21 double baseSalary; // base salary per week
22
23 }; // end class BasePlusCommissionEmployee
24
25 #endif // BASEPLUS_H

 2003 Prentice Hall, Inc.


All rights reserved.
86
1 // Fig. 10.32: baseplus.cpp
2 // BasePlusCommissionEmployee member-function definitions.
Outline
3 #include <iostream>
4
baseplus.cpp
5 using std::cout;
(1 of 2)
6
7 #include "baseplus.h"
8
9 // constructor for class BasePlusCommissionEmployee
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee(
11 const string &first, const string &last,
12 const string &socialSecurityNumber,
13 double grossSalesAmount, double rate,
14 double baseSalaryAmount )
15 : CommissionEmployee( first, last, socialSecurityNumber,
16 grossSalesAmount, rate )
17 {
18 setBaseSalary( baseSalaryAmount );
19
20 } // end BasePlusCommissionEmployee constructor
21
22 // set base-salaried commission employee's wage
23 void BasePlusCommissionEmployee::setBaseSalary( double salary )
24 {
25 baseSalary = salary < 0.0 ? 0.0 : salary;
26
27 } // end function setBaseSalary

 2003 Prentice Hall, Inc.


All rights reserved.
87
28
29 // return base-salaried commission employee's base salary
Outline
30 double BasePlusCommissionEmployee::getBaseSalary() const
31 {
baseplus.cpp
32 return baseSalary;
(2 of 2)
33
34 } // end function getBaseSalary
35
36 // return base-salaried commission employee's earnings
37 double BasePlusCommissionEmployee::earnings() const
38 {
39 return getBaseSalary() + CommissionEmployee::earnings();
40
41 } // end function earnings
42
43 // print base-salaried commission employee's name
44 void BasePlusCommissionEmployee::print() const
45 {
46 cout << "\nbase-salaried commission employee: ";
47 Employee::print(); // code reuse
48
49 } // end function print

 2003 Prentice Hall, Inc.


All rights reserved.
88
1 // Fig. 10.33: fig10_33.cpp
2 // Driver for Employee hierarchy.
Outline
3 #include <iostream>
4
fig10_33.cpp
5 using std::cout;
(1 of 4)
6 using std::endl;
7 using std::fixed;
8
9 #include <iomanip>
10
11 using std::setprecision;
12
13 #include <vector>
14
15 using std::vector;
16
17 #include <typeinfo>
18
19 #include "employee.h" // Employee base class
20 #include "salaried.h" // SalariedEmployee class
21 #include "commission.h" // CommissionEmployee class
22 #include "baseplus.h" // BasePlusCommissionEmployee class
23 #include "hourly.h" // HourlyEmployee class
24

 2003 Prentice Hall, Inc.


All rights reserved.
89
25 int main()
26 {
Outline
27 // set floating-point output formatting
28 cout << fixed << setprecision( 2 );
fig10_33.cpp
29
(2 of 4)
30 // create vector employees
31 vector < Employee * > employees( 4 );
32
33 // initialize vector with Employees
34 employees[ 0 ] = new SalariedEmployee( "John", "Smith",
35 "111-11-1111", 800.00 );
36 employees[ 1 ] = new CommissionEmployee( "Sue", "Jones",
37 "222-22-2222", 10000, .06 );
38 employees[ 2 ] = new BasePlusCommissionEmployee( "Bob",
39 "Lewis", "333-33-3333", 300, 5000, .04 );
40 employees[ 3 ] = new HourlyEmployee( "Karen", "Price",
41 "444-44-4444", 16.75, 40 );
42

 2003 Prentice Hall, Inc.


All rights reserved.
90
43 // generically process each element in vector employees
44
Use downcasting to
for ( int i = 0; i < employees.size(); i++ ) {
cast the employee objectOutline
into a
45 BasePlusCommissionEmployee. If it points to
46 // output employee information the correct type of object, the pointer is non-zero. This
fig10_33.cpp
47 employees[ i ]->print(); way, we can give a raise to only
(3 of 4)
48 BasePlusCommissionEmployees.
49 // downcast pointer
50 BasePlusCommissionEmployee *commissionPtr =
51 dynamic_cast < BasePlusCommissionEmployee * >
52 ( employees[ i ] );
53
54 // determine whether element points to base-salaried
55 // commission employee
56 if ( commissionPtr != 0 ) {
57 cout << "old base salary: $"
58 << commissionPtr->getBaseSalary() << endl;
59 commissionPtr->setBaseSalary(
60 1.10 * commissionPtr->getBaseSalary() );
61 cout << "new base salary with 10% increase is: $"
62 << commissionPtr->getBaseSalary() << endl;
63
64 } // end if
65
66 cout << "earned $" << employees[ i ]->earnings() << endl;
67
68 } // end for
69

 2003 Prentice Hall, Inc.


All rights reserved.
91
70 // release memory held by vector employees
71 for ( int j = 0; j < employees.size(); j++ ) {
Outline
72
73 // output class name
fig10_33.cpp
74 cout << "\ndeleting object of "
(4 of 4)
75 << typeid( *employees[ j ] ).name();
76
77 delete employees[ j ];
78
79 } // end for
typeid returns a
80
81 cout << endl;
type_info object. This
82 object contains information
83 return 0; about the operand, including
84 its name.
85 } // end main

 2003 Prentice Hall, Inc.


All rights reserved.
92
salaried employee: John Smith
social security number: 111-11-1111
Outline
earned $800.00

fig10_33.cpp
commission employee: Sue Jones
output (1 of 1)
social security number: 222-22-2222
earned $600.00

base-salaried commission employee: Bob Lewis


social security number: 333-33-3333
old base salary: $300.00
new base salary with 10% increase is: $330.00
earned $530.00

hourly employee: Karen Price


social security number: 444-44-4444
earned $670.00

deleting object of class SalariedEmployee


deleting object of class CommissionEmployee
deleting object of class BasePlusCommissionEmployee
deleting object of class HourlyEmployee

 2003 Prentice Hall, Inc.


All rights reserved.

You might also like