+ All Categories
Home > Documents > Object Oriented Programming...

Object Oriented Programming...

Date post: 06-Feb-2018
Category:
Upload: vokiet
View: 227 times
Download: 1 times
Share this document with a friend
32
24 Object- Oriented Programming: Polymorphism OBJECTIVES In this chapter you will learn: What polymorphism is, how it makes programming more convenient, and how it makes systems more extensible and maintainable. To declare and use virtual functions to effect polymorphism. The distinction between abstract and concrete classes. To declare pure virtual functions to create abstract classes. How to use run-time type information (RTTI) with downcasting, dynamic_cast, typeid and type_info. How C++ implements virtual functions and dynamic binding “under the hood.” How to use virtual destructors to ensure that all appropriate destructors run on an object. One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them. —John Ronald Reuel Tolkien The silence often of pure innocence Persuades when speaking fails. —William Shakespeare General propositions do not decide concrete cases. —Oliver Wendell Holmes A philosopher of imposing stature doesn’t think in a vacuum. Even his most abstract ideas are, to some extent, conditioned by what is or is not known in the time when he lives. —Alfred North Whitehead
Transcript
Page 1: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

24Object-OrientedProgramming:Polymorphism

O B J E C T I V E SIn this chapter you will learn:

■ What polymorphism is, how it makes programmingmore convenient, and how it makes systems moreextensible and maintainable.

■ To declare and use virtual functions to effectpolymorphism.

■ The distinction between abstract and concrete classes.

■ To declare pure virtual functions to create abstractclasses.

■ How to use run-time type information (RTTI) withdowncasting, dynamic_cast, typeid andtype_info.

■ How C++ implements virtual functions and dynamicbinding “under the hood.”

■ How to use virtual destructors to ensure that allappropriate destructors run on an object.

One Ring to rule them all,One Ring to find them,One Ring to bring them alland in the darkness bindthem.—John Ronald Reuel Tolkien

The silence often of pureinnocencePersuades when speakingfails.—William Shakespeare

General propositions do notdecide concrete cases.—Oliver Wendell Holmes

A philosopher of imposingstature doesn’t think in avacuum. Even his mostabstract ideas are, to someextent, conditioned by whatis or is not known in the timewhen he lives.—Alfred North Whitehead

Page 2: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

2 Chapter 24 Object-Oriented Programming: Polymorphism

Self-Review Exercises24.1 Fill in the blanks in each of the following statements:

a) Treating a base-class object as a(n) can cause errors.ANS: derived-class object.b) Polymorphism helps eliminate logic.ANS: switch.c) If a class contains at least one pure virtual function, it is a(n) class.ANS: abstract.d) Classes from which objects can be instantiated are called classes.ANS: concrete.e) Operator can be used to downcast base-class pointers safely.ANS: dynamic_cast.f) Operator typeid returns a reference to a(n) object.ANS: type_info.g) involves using a base-class pointer or reference to invoke virtual functions

on base-class and derived-class objects.ANS: Polymorphism.h) Overridable functions are declared using keyword .ANS: virtual.i) Casting a base-class pointer to a derived-class pointer is called .ANS: downcasting.

24.2 State whether each of the following is true or false. If false, explain why.a) All virtual functions in an abstract base class must be declared as pure virtual func-

tions.ANS: False. An abstract base class can include virtual functions with implementations.b) Referring to a derived-class object with a base-class handle is dangerous.ANS: False. Referring to a base-class object with a derived-class handle is dangerous.c) A class is made abstract by declaring that class virtual.ANS: False. Classes are never declared virtual. Rather, a class is made abstract by including

at least one pure virtual function in the class.d) If a base class declares a pure virtual function, a derived class must implement that

function to become a concrete class.ANS: True.e) Polymorphic programming can eliminate the need for switch logic.ANS: True.

Exercises24.3 How is it that polymorphism enables you to program “in the general” rather than “in thespecific”? Discuss the key advantages of programming “in the general.”

ANS: Polymorphism enables the programmer to concentrate on the common operationsthat are applied to objects of all the classes in a hierarchy. The general processing ca-pabilities can be separated from any code that is specific to each class. Those generalportions of the code can accommodate new classes without modification. In somepolymorphic applications, only the code that creates the objects needs to be modifiedto extend the system with new classes.

Page 3: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 3

24.4 Discuss the problems of programming with switch logic. Explain why polymorphism canbe an effective alternative to using switch logic.

ANS: The main problems with programming using switch logic are extensibility and pro-gram maintainability. A program containing many switch statements is difficult tomodify. A programmer will need to add or remove cases from many, possibly all,switch statements in the program as the types of objects in the program change. Thepolymorphic approach eliminates these issues, as new types can be added to a pro-gram with relative ease. Only the part of the program that creates objects needs to beaware of the newly added types. [Note: switch logic includes if…else statementswhich are more flexible than the switch statement.]

24.5 What are virtual functions? Describe a circumstance in which virtual functions wouldbe appropriate.

ANS: virtual functions are functions with the same function prototype that are definedthroughout a class hierarchy. At least the base class occurrence of the function is pre-ceded by the keyword virtual. Programmers use virtual function to enable genericprocessing of an entire class hierarchy of objects through a base-class pointer. If theprogram invokes a virtual function through a base-class pointer to a derived-classobject, the program will choose the correct derived-class function dynamically (i.e.,at execution time) based on the object type—not the pointer type. For example, in ashape hierarchy, all shapes can be drawn. If all shapes are derived from a base classShape which contains a virtual draw function, then generic processing of the hierar-chy can be performed by calling every shape’s draw generically through a base classShape pointer.

24.6 Distinguish between static binding and dynamic binding. Explain the use of virtual func-tions and the vtable in dynamic binding.

ANS: Static binding is performed at compile-time when a function is called via a specificobject or via a pointer to an object. Dynamic binding is performed at run-time whena virtual function is called via a base-class pointer to a derived-class object (the ob-ject can be of any derived class). The virtual functions table (vtable) is used at run-time to enable the proper function to be called for the object to which the base-classpointer “points”. Each class containing virtual functions has its own vtable thatspecifies where the virtual functions for that class are located. Every object of a classwith virtual functions contains a hidden pointer to the class’s vtable. When a vir-

tual function is called via a base-class pointer, the hidden pointer is dereferenced tolocate the vtable, then the vtable is searched for the proper function call.

24.7 Distinguish between virtual functions and pure virtual functions.ANS: A virtual function must have a definition in the class in which it is declared. A pure

virtual function does not provide a definition. A pure virtual function is appropri-ate when it does not make sense to provide an implementation for a function in abase class (i.e., some additional derived-class-specific data is required to implementthe function in a meaningful manner). Classes derived directly from the abstract classmust provide definitions for the inherited pure virtual functions to become a con-crete class; otherwise, the derived class becomes an abstract class as well.

Page 4: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

4 Chapter 24 Object-Oriented Programming: Polymorphism

24.8 Suggest one or more levels of abstract base classes for the Shape hierarchy discussed in thischapter and shown in Fig. 23.3. (The first level is Shape, and the second level consists of the classesTwoDimensionalShape and ThreeDimensionalShape.)

ANS: In the Shape hierarchy, class Shape could be an abstract base class. In the second levelof the hierarchy, TwoDimensionalShape and ThreeDimensionalShape could also beabstract base classes, as defining a function such as draw does not make sense for ei-ther a generic two-dimensional shape or a generic three-dimensional shape.

24.9 How does polymorphism promote extensibility?ANS: Polymorphism makes programs more extensible by making all function calls generic.

When a new class type with the appropriate virtual functions is added to the hier-archy, no changes need to be made to the generic function calls. Only client code thatinstantiates new objects must be modified to accommodate new types.

24.10 (Payroll System Modification) Modify the payroll system of Figs. 24.13–24.23 to includeprivate data member birthDate in class Employee. Use class Date from Figs. 22.12–22.13 to rep-resent an employee’s birthday. Assume that payroll is processed once per month. Create a vector ofEmployee references to store the various employee objects. In a loop, calculate the payroll for eachEmployee (polymorphically), and add a $100.00 bonus to the person’s payroll amount if the currentmonth is the month in which the Employee’s birthday occurs.

ANS:

1 // Exercise 24.10 Solution: Date.h2 // Date class definition.3 #ifndef DATE_H4 #define DATE_H56 #include <iostream>7 using std::ostream;89 class Date

10 {11 friend ostream &operator<<( ostream &, const Date & );12 public:13 Date( int m = 1, int d = 1, int y = 1900 ); // default constructor14 void setDate( int, int, int ); // set month, day, year15 Date &operator++(); // prefix increment operator16 Date operator++( int ); // postfix increment operator17 const Date &operator+=( int ); // add days, modify object18 bool leapYear( int ) const; // is date in a leap year?19 bool endOfMonth( int ) const; // is date at the end of month?20 int getMonth() const; // return the month of the date21 private:22 int month;23 int day;24 int year;2526 static const int days[]; // array of days per month27 void helpIncrement(); // utility function for incrementing date28 }; // end class Date2930 #endif

Page 5: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 5

1 // Exercise 24.10 Solution: Date.cpp2 // Date class member-function definitions.3 #include <iostream>4 #include "Date.h"56 // initialize static member at file scope; one classwide copy7 const int Date::days[] =8 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };9

10 // Date constructor11 Date::Date( int m, int d, int y )12 {13 setDate( m, d, y );14 } // end Date constructor1516 // set month, day and year17 void Date::setDate( int mm, int dd, int yy )18 {19 month = ( mm >= 1 && mm <= 12 ) ? mm : 1;20 year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900;2122 // test for a leap year23 if ( month == 2 && leapYear( year ) )24 day = ( dd >= 1 && dd <= 29 ) ? dd : 1;25 else26 day = ( dd >= 1 && dd <= days[ month ] ) ? dd : 1;27 } // end function setDate2829 // overloaded prefix increment operator30 Date &Date::operator++()31 {32 helpIncrement(); // increment date33 return *this; // reference return to create an lvalue34 } // end function operator++3536 // overloaded postfix increment operator; note that the37 // dummy integer parameter does not have a parameter name38 Date Date::operator++( int )39 {40 Date temp = *this; // hold current state of object41 helpIncrement();4243 // return unincremented, saved, temporary object44 return temp; // value return; not a reference return45 } // end function operator++4647 // add specified number of days to date48 const Date &Date::operator+=( int additionalDays )49 {50 for ( int i = 0; i < additionalDays; i++ )51 helpIncrement();5253 return *this; // enables cascading54 } // end function operator+=55

Page 6: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

6 Chapter 24 Object-Oriented Programming: Polymorphism

56 // if the year is a leap year, return true; otherwise, return false57 bool Date::leapYear( int testYear ) const58 {59 if ( testYear % 400 == 0 ||60 ( testYear % 100 != 0 && testYear % 4 == 0 ) )61 return true; // a leap year62 else63 return false; // not a leap year64 } // end function leapYear6566 // return the month of the date67 int Date::getMonth() const68 {69 return month;70 } // end function getMonth7172 // determine whether the day is the last day of the month73 bool Date::endOfMonth( int testDay ) const74 {75 if ( month == 2 && leapYear( year ) )76 return testDay == 29; // last day of Feb. in leap year77 else78 return testDay == days[ month ];79 } // end function endOfMonth8081 // function to help increment the date82 void Date::helpIncrement()83 {84 // day is not end of month85 if ( !endOfMonth( day ) )86 day++; // increment day87 else88 if ( month < 12 ) // day is end of month and month < 1289 {90 month++; // increment month91 day = 1; // first day of new month92 } // end if93 else // last day of year94 {95 year++; // increment year96 month = 1; // first month of new year97 day = 1; // first day of new month98 } // end else99 } // end function helpIncrement100101 // overloaded output operator102 ostream &operator<<( ostream &output, const Date &d )103 {104 static char *monthName[ 13 ] = { "", "January", "February",105 "March", "April", "May", "June", "July", "August",106 "September", "October", "November", "December" };107 output << monthName[ d.month ] << ' ' << d.day << ", " << d.year;108 return output; // enables cascading109 } // end function operator<<

Page 7: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 7

1 // Exercise 24.10 Solution: Employee.h2 // Employee abstract base class.3 #ifndef EMPLOYEE_H4 #define EMPLOYEE_H56 #include <string> // C++ standard string class7 using std::string;89 #include "Date.h" // Date class definition

1011 class Employee12 {13 public:14 Employee( const string &, const string &, const string &,15 int, int, int );1617 void setFirstName( const string & ); // set first name18 string getFirstName() const; // return first name1920 void setLastName( const string & ); // set last name21 string getLastName() const; // return last name2223 void setSocialSecurityNumber( const string & ); // set SSN24 string getSocialSecurityNumber() const; // return SSN2526 void setBirthDate( int, int, int ); // set birthday27 Date getBirthDate() const; // return birthday2829 // pure virtual function makes Employee abstract base class30 virtual double earnings() const = 0; // pure virtual31 virtual void print() const; // virtual32 private:33 string firstName;34 string lastName;35 string socialSecurityNumber;36 Date birthDate; // the Employee's birthday37 }; // end class Employee3839 #endif // EMPLOYEE_H

1 // Exercise 24.10 Solution: Employee.cpp2 // Abstract-base-class Employee member-function definitions.3 // Note: No definitions are given for pure virtual functions.4 #include <iostream>5 using std::cout;67 #include "Employee.h" // Employee class definition89 // constructor

10 Employee::Employee( const string &first, const string &last,11 const string &ssn, int month, int day, int year )12 : firstName( first ), lastName( last ), socialSecurityNumber( ssn ),13 birthDate( month, day, year )

Page 8: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

8 Chapter 24 Object-Oriented Programming: Polymorphism

14 {15 // empty body16 } // end Employee constructor1718 // set first name19 void Employee::setFirstName( const string &first )20 {21 firstName = first;22 } // end function setFirstName2324 // return first name25 string Employee::getFirstName() const26 {27 return firstName;28 } // end function getFirstName2930 // set last name31 void Employee::setLastName( const string &last )32 {33 lastName = last;34 } // end function setLastName3536 // return last name37 string Employee::getLastName() const38 {39 return lastName;40 } // end function getLastName4142 // set social security number43 void Employee::setSocialSecurityNumber( const string &ssn )44 {45 socialSecurityNumber = ssn; // should validate46 } // end function setSocialSecurityNumber4748 // return social security number49 string Employee::getSocialSecurityNumber() const50 {51 return socialSecurityNumber;52 } // end function getSocialSecurityNumber5354 // set birthday55 void Employee::setBirthDate( int month, int day, int year )56 {57 birthDate.setDate( month, day, year );58 } // end function setBirthDate5960 // return birthday61 Date Employee::getBirthDate() const62 {63 return birthDate;64 } // end function getBirthDate65

Page 9: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 9

66 // print Employee's information (virtual, but not pure virtual)67 void Employee::print() const68 {69 cout << getFirstName() << ' ' << getLastName()70 << "\nbirthday: " << getBirthDate()71 << "\nsocial security number: " << getSocialSecurityNumber();72 } // end function print

1 // Exercise 24.10 Solution: SalariedEmployee.h2 // SalariedEmployee class derived from Employee.3 #ifndef SALARIED_H4 #define SALARIED_H56 #include "Employee.h" // Employee class definition78 class SalariedEmployee : public Employee9 {

10 public:11 SalariedEmployee( const string &, const string &,12 const string &, int, int, int, double = 0.0 );1314 void setWeeklySalary( double ); // set weekly salary15 double getWeeklySalary() const; // return weekly salary1617 // keyword virtual signals intent to override18 virtual double earnings() const; // calculate earnings19 virtual void print() const; // print SalariedEmployee object20 private:21 double weeklySalary; // salary per week22 }; // end class SalariedEmployee2324 #endif // SALARIED_H

1 // Exercise 24.10 Solution: SalariedEmployee.cpp2 // SalariedEmployee class member-function definitions.3 #include <iostream>4 using std::cout;56 #include "SalariedEmployee.h" // SalariedEmployee class definition78 // constructor9 SalariedEmployee::SalariedEmployee( const string &first,

10 const string &last, const string &ssn, int month, int day, int year,11 double salary )12 : Employee( first, last, ssn, month, day, year )13 {14 setWeeklySalary( salary );15 } // end SalariedEmployee constructor1617 // set salary18 void SalariedEmployee::setWeeklySalary( double salary )19 {20 weeklySalary = ( salary < 0.0 ) ? 0.0 : salary;21 } // end function setWeeklySalary

Page 10: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

10 Chapter 24 Object-Oriented Programming: Polymorphism

2223 // return salary24 double SalariedEmployee::getWeeklySalary() const25 {26 return weeklySalary;27 } // end function getWeeklySalary2829 // calculate earnings;30 // override pure virtual function earnings in Employee31 double SalariedEmployee::earnings() const32 {33 return getWeeklySalary();34 } // end function earnings3536 // print SalariedEmployee's information37 void SalariedEmployee::print() const38 {39 cout << "salaried employee: ";40 Employee::print(); // reuse abstract base-class print function41 cout << "\nweekly salary: " << getWeeklySalary();42 } // end function print

1 // Exercise 24.10 Solution: HourlyEmployee.h2 // HourlyEmployee class definition.3 #ifndef HOURLY_H4 #define HOURLY_H56 #include "Employee.h" // Employee class definition78 class HourlyEmployee : public Employee9 {

10 public:11 HourlyEmployee( const string &, const string &,12 const string &, int, int, int, double = 0.0, double = 0.0 );1314 void setWage( double ); // set hourly wage15 double getWage() const; // return hourly wage1617 void setHours( double ); // set hours worked18 double getHours() const; // return hours worked1920 // keyword virtual signals intent to override21 virtual double earnings() const; // calculate earnings22 virtual void print() const; // print HourlyEmployee object23 private:24 double wage; // wage per hour25 double hours; // hours worked for week26 }; // end class HourlyEmployee2728 #endif // HOURLY_H

Page 11: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 11

1 // Exercise 24.10 Solution: HourlyEmployee.cpp2 // HourlyEmployee class member-function definitions.3 #include <iostream>4 using std::cout;56 #include "HourlyEmployee.h" // HourlyEmployee class definition78 // constructor9 HourlyEmployee::HourlyEmployee( const string &first, const string &last,

10 const string &ssn, int month, int day, int year,11 double hourlyWage, double hoursWorked )12 : Employee( first, last, ssn, month, day, year )13 {14 setWage( hourlyWage ); // validate hourly wage15 setHours( hoursWorked ); // validate hours worked16 } // end HourlyEmployee constructor1718 // set wage19 void HourlyEmployee::setWage( double hourlyWage )20 {21 wage = ( hourlyWage < 0.0 ? 0.0 : hourlyWage );22 } // end function setWage2324 // return wage25 double HourlyEmployee::getWage() const26 {27 return wage;28 } // end function getWage2930 // set hours worked31 void HourlyEmployee::setHours( double hoursWorked )32 {33 hours = ( ( ( hoursWorked >= 0.0 ) && ( hoursWorked <= 168.0 ) ) ?34 hoursWorked : 0.0 );35 } // end function setHours3637 // return hours worked38 double HourlyEmployee::getHours() const39 {40 return hours;41 } // end function getHours4243 // calculate earnings;44 // override pure virtual function earnings in Employee45 double HourlyEmployee::earnings() const46 {47 if ( getHours() <= 40 ) // no overtime48 return getWage() * getHours();49 else50 return 40 * getWage() + ( ( getHours() - 40 ) * getWage() * 1.5 );51 } // end function earnings52

Page 12: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

12 Chapter 24 Object-Oriented Programming: Polymorphism

53 // print HourlyEmployee's information54 void HourlyEmployee::print() const55 {56 cout << "hourly employee: ";57 Employee::print(); // code reuse58 cout << "\nhourly wage: " << getWage() <<59 "; hours worked: " << getHours();60 } // end function print

1 // Exercise 24.10 Solution: CommissionEmployee.h2 // CommissionEmployee class derived from Employee.3 #ifndef COMMISSION_H4 #define COMMISSION_H56 #include "Employee.h" // Employee class definition78 class CommissionEmployee : public Employee9 {

10 public:11 CommissionEmployee( const string &, const string &,12 const string &, int, int, int, double = 0.0, double = 0.0 );1314 void setCommissionRate( double ); // set commission rate15 double getCommissionRate() const; // return commission rate1617 void setGrossSales( double ); // set gross sales amount18 double getGrossSales() const; // return gross sales amount1920 // keyword virtual signals intent to override21 virtual double earnings() const; // calculate earnings22 virtual void print() const; // print CommissionEmployee object23 private:24 double grossSales; // gross weekly sales25 double commissionRate; // commission percentage26 }; // end class CommissionEmployee2728 #endif // COMMISSION_H

1 // Exercise 24.10 Solution: CommissionEmployee.cpp2 // CommissionEmployee class member-function definitions.3 #include <iostream>4 using std::cout;56 #include "CommissionEmployee.h" // CommissionEmployee class definition78 // constructor9 CommissionEmployee::CommissionEmployee( const string &first,

10 const string &last, const string &ssn, int month, int day, int year,11 double sales, double rate )12 : Employee( first, last, ssn, month, day, year )13 {14 setGrossSales( sales );15 setCommissionRate( rate );16 } // end CommissionEmployee constructor

Page 13: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 13

1718 // set commission rate19 void CommissionEmployee::setCommissionRate( double rate )20 {21 commissionRate = ( ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0 );22 } // end function setCommissionRate2324 // return commission rate25 double CommissionEmployee::getCommissionRate() const26 {27 return commissionRate;28 } // end function getCommissionRate2930 // set gross sales amount31 void CommissionEmployee::setGrossSales( double sales )32 {33 grossSales = ( ( sales < 0.0 ) ? 0.0 : sales );34 } // end function setGrossSales3536 // return gross sales amount37 double CommissionEmployee::getGrossSales() const38 {39 return grossSales;40 } // end function getGrossSales4142 // calculate earnings;43 // override pure virtual function earnings in Employee44 double CommissionEmployee::earnings() const45 {46 return getCommissionRate() * getGrossSales();47 } // end function earnings4849 // print CommissionEmployee's information50 void CommissionEmployee::print() const51 {52 cout << "commission employee: ";53 Employee::print(); // code reuse54 cout << "\ngross sales: " << getGrossSales()55 << "; commission rate: " << getCommissionRate();56 } // end function print

1 // Exercise 24.10 Solution: BasePlusCommissionEmployee.h2 // BasePlusCommissionEmployee class derived from Employee.3 #ifndef BASEPLUS_H4 #define BASEPLUS_H56 #include "CommissionEmployee.h" // CommissionEmployee class definition78 class BasePlusCommissionEmployee : public CommissionEmployee9 {

10 public:11 BasePlusCommissionEmployee( const string &, const string &,12 const string &, int, int, int, double = 0.0, double = 0.0,13 double = 0.0 );

Page 14: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

14 Chapter 24 Object-Oriented Programming: Polymorphism

1415 void setBaseSalary( double ); // set base salary16 double getBaseSalary() const; // return base salary1718 // keyword virtual signals intent to override19 virtual double earnings() const; // calculate earnings20 virtual void print() const; // print BasePlusCommissionEmployee object21 private:22 double baseSalary; // base salary per week23 }; // end class BasePlusCommissionEmployee2425 #endif // BASEPLUS_H

1 // Exercise 24.10 Solution: BasePlusCommissionEmployee.cpp2 // BasePlusCommissionEmployee member-function definitions.3 #include <iostream>4 using std::cout;56 // BasePlusCommissionEmployee class definition7 #include "BasePlusCommissionEmployee.h"89 // constructor

10 BasePlusCommissionEmployee::BasePlusCommissionEmployee(11 const string &first, const string &last, const string &ssn,12 int month, int day, int year, double sales,13 double rate, double salary )14 : CommissionEmployee( first, last, ssn, month, day, year, sales, rate )15 {16 setBaseSalary( salary ); // validate and store base salary17 } // end BasePlusCommissionEmployee constructor1819 // set base salary20 void BasePlusCommissionEmployee::setBaseSalary( double salary )21 {22 baseSalary = ( ( salary < 0.0 ) ? 0.0 : salary );23 } // end function setBaseSalary2425 // return base salary26 double BasePlusCommissionEmployee::getBaseSalary() const27 {28 return baseSalary;29 } // end function getBaseSalary3031 // calculate earnings;32 // override pure virtual function earnings in Employee33 double BasePlusCommissionEmployee::earnings() const34 {35 return getBaseSalary() + CommissionEmployee::earnings();36 } // end function earnings37

Page 15: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 15

38 // print BasePlusCommissionEmployee's information39 void BasePlusCommissionEmployee::print() const40 {41 cout << "base-salaried ";42 CommissionEmployee::print(); // code reuse43 cout << "; base salary: " << getBaseSalary();44 } // end function print

1 // Exercise 24.10 Solution: ex24_10.cpp2 // Processing Employee derived-class objects polymorphically.3 #include <iostream>4 using std::cout;5 using std::endl;6 using std::fixed;78 #include <iomanip>9 using std::setprecision;

1011 #include <vector>12 using std::vector;1314 #include <typeinfo>1516 #include <ctime>17 using std::time_t;18 using std::time;19 using std::localtime;20 using std::strftime;2122 #include <cstdlib>23 using std::atoi;2425 // include definitions of classes in Employee hierarchy26 #include "Employee.h"27 #include "SalariedEmployee.h"28 #include "HourlyEmployee.h"29 #include "CommissionEmployee.h"30 #include "BasePlusCommissionEmployee.h"3132 int determineMonth(); // prototype of function that returns current month3334 int main()35 {36 // set floating-point output formatting37 cout << fixed << setprecision( 2 );3839 // create vector of four base-class pointers40 vector < Employee * > employees( 4 );4142 // initialize vector with Employees43 employees[ 0 ] = new SalariedEmployee(44 "John", "Smith", "111-11-1111", 6, 15, 1944, 800 );45 employees[ 1 ] = new HourlyEmployee(46 "Karen", "Price", "222-22-2222", 12, 29, 1960, 16.75, 40 );

Page 16: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

16 Chapter 24 Object-Oriented Programming: Polymorphism

47 employees[ 2 ] = new CommissionEmployee(48 "Sue", "Jones", "333-33-3333", 9, 8, 1954, 10000, .06 );49 employees[ 3 ] = new BasePlusCommissionEmployee(50 "Bob", "Lewis", "444-44-4444", 3, 2, 1965, 5000, .04, 300 );5152 int month = determineMonth();5354 cout << "Employees processed polymorphically via dynamic binding:\n\n";5556 for ( size_t i = 0; i < employees.size(); i++ )57 {58 employees[ i ]->print(); // output employee information59 cout << endl;6061 // downcast pointer62 BasePlusCommissionEmployee *derivedPtr =63 dynamic_cast < BasePlusCommissionEmployee * >64 ( employees[ i ] );6566 // determine whether element points to base-salaried67 // commission employee68 if ( derivedPtr != 0 ) // 0 if not a BasePlusCommissionEmployee69 {70 double oldBaseSalary = derivedPtr->getBaseSalary();71 cout << "old base salary: $" << oldBaseSalary << endl;72 derivedPtr->setBaseSalary( 1.10 * oldBaseSalary );73 cout << "new base salary with 10% increase is: $"74 << derivedPtr->getBaseSalary() << endl;75 } // end if7677 // get current employee's birthday78 Date birthday = employees[ i ]->getBirthDate();7980 // if current month is employee's birthday month, add $100 to salary81 if ( birthday.getMonth() == month )82 cout << "HAPPY BIRTHDAY!\nearned $"83 << ( employees[ i ]->earnings() + 100.0 ) << endl;84 else85 cout << "earned $" << employees[ i ]->earnings() << endl;8687 cout << endl;88 } // end for8990 // release objects pointed to by vector’s elements91 for ( size_t j = 0; j < employees.size(); j++ )92 {93 // output class name94 cout << "deleting object of "95 << typeid( *employees[ j ] ).name() << endl;9697 delete employees[ j ];98 } // end for99100 return 0;101 } // end main

Page 17: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 17

24.11 (Package Inheritance Hierarchy) Use the Package inheritance hierarchy created inExercise 23.5 to create a program that displays the address information and calculates the shippingcosts for several Packages. The program should contain a vector of Package pointers to objects ofclasses TwoDayPackage and OvernightPackage. Loop through the vector to process the Packagespolymorphically. For each Package, invoke get functions to obtain the address information of the

102103 // Determine the current month using standard library functions of ctime104 int determineMonth()105 {106 time_t currentTime;107 char monthString[ 3 ];108 time( &currentTime );109 strftime( monthString, 3, "%m", localtime( &currentTime ) );110 return atoi( monthString );111 } // end function determineMonth

Employees processed polymorphically via dynamic binding:

salaried employee: John Smithbirthday: June 15, 1944social security number: 111-11-1111weekly salary: 800.00earned $800.00

hourly employee: Karen Pricebirthday: December 29, 1960social security number: 222-22-2222hourly wage: 16.75; hours worked: 40.00HAPPY BIRTHDAY!earned $770.00

commission employee: Sue Jonesbirthday: September 8, 1954social security number: 333-33-3333gross sales: 10000.00; commission rate: 0.06earned $600.00

base-salaried commission employee: Bob Lewisbirthday: March 2, 1965social security number: 444-44-4444gross sales: 5000.00; commission rate: 0.04; base salary: 300.00old base salary: $300.00new base salary with 10% increase is: $330.00earned $530.00

deleting object of class SalariedEmployeedeleting object of class HourlyEmployeedeleting object of class CommissionEmployeedeleting object of class BasePlusCommissionEmployee

Page 18: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

18 Chapter 24 Object-Oriented Programming: Polymorphism

sender and the recipient, then print the two addresses as they would appear on mailing labels. Also,call each Package’s calculateCost member function and print the result. Keep track of the totalshipping cost for all Packages in the vector, and display this total when the loop terminates.

ANS: [Note: To achieve polymorphic behavior in the Package hierarchy, each class defini-tion must declare the calculateCost member function as a virtual function.]

1 // Exercise 24.11 Solution: Package.h2 // Definition of base class Package.3 #ifndef PACKAGE_H4 #define PACKAGE_H56 #include <string>7 using std::string;89 class Package

10 {11 public:12 // constructor initiliazes data members13 Package( const string &, const string &, const string &,14 const string &, int, const string &, const string &, const string &,15 const string &, int, double, double );1617 void setSenderName( const string & ); // set sender's name18 string getSenderName() const; // return sender's name19 void setSenderAddress( const string & ); // set sender's address20 string getSenderAddress() const; // return sender's address21 void setSenderCity( const string & ); // set sender's city22 string getSenderCity() const; // return sender's city23 void setSenderState( const string & ); // set sender's state24 string getSenderState() const; // return sender's state25 void setSenderZIP( int ); // set sender's ZIP code26 int getSenderZIP() const; // return sender's ZIP code27 void setRecipientName( const string & ); // set recipient's name28 string getRecipientName() const; // return recipient's name29 void setRecipientAddress( const string & ); // set recipient's address30 string getRecipientAddress() const; // return recipient's address31 void setRecipientCity( const string & ); // set recipient's city32 string getRecipientCity() const; // return recipient's city33 void setRecipientState( const string & ); // set recipient's state34 string getRecipientState() const; // return recipient's state35 void setRecipientZIP( int ); // set recipient's ZIP code36 int getRecipientZIP() const; // return recipient's ZIP code37 void setWeight( double ); // validate and store weight38 double getWeight() const; // return weight of package39 void setCostPerOunce( double ); // validate and store cost per ounce40 double getCostPerOunce() const; // return cost per ounce4142 virtual double calculateCost() const; // calculate shipping cost43 private:44 // data members to store sender and recipient's address information45 string senderName;46 string senderAddress;47 string senderCity;48 string senderState;49 int senderZIP;

Page 19: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 19

50 string recipientName;51 string recipientAddress;52 string recipientCity;53 string recipientState;54 int recipientZIP;5556 double weight; // weight of the package57 double costPerOunce; // cost per ounce to ship the package58 }; // end class Package5960 #endif

1 // Exercise 24.11 Solution: Package.cpp2 // Member-function definitions of class Package.34 #include "Package.h" // Package class definition56 // constructor initiliazes data members7 Package::Package( const string &sName, const string &sAddress,8 const string &sCity, const string &sState, int sZIP,9 const string &rName, const string &rAddress, const string &rCity,

10 const string &rState, int rZIP, double w, double cost )11 : senderName( sName ), senderAddress( sAddress ), senderCity( sCity ),12 senderState( sState ), senderZIP( sZIP ), recipientName( rName ),13 recipientAddress( rAddress ), recipientCity( rCity ),14 recipientState( rState ), recipientZIP( rZIP )15 {16 setWeight( w ); // validate and store weight17 setCostPerOunce( cost ); // validate and store cost per ounce18 } // end Package constructor1920 // set sender's name21 void Package::setSenderName( const string &name )22 {23 senderName = name;24 } // end function setSenderName2526 // return sender's name27 string Package::getSenderName() const28 {29 return senderName;30 } // end function getSenderName3132 // set sender's address33 void Package::setSenderAddress( const string &address )34 {35 senderAddress = address;36 } // end function setSenderAddress3738 // return sender's address39 string Package::getSenderAddress() const40 {41 return senderAddress;42 } // end function getSenderAddress

Page 20: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

20 Chapter 24 Object-Oriented Programming: Polymorphism

4344 // set sender's city45 void Package::setSenderCity( const string &city )46 {47 senderCity = city;48 } // end function setSenderCity4950 // return sender's city51 string Package::getSenderCity() const52 {53 return senderCity;54 } // end function getSenderCity5556 // set sender's state57 void Package::setSenderState( const string &state )58 {59 senderState = state;60 } // end function setSenderState6162 // return sender's state63 string Package::getSenderState() const64 {65 return senderState;66 } // end function getSenderState6768 // set sender's ZIP code69 void Package::setSenderZIP( int zip )70 {71 senderZIP = zip;72 } // end function setSenderZIP7374 // return sender's ZIP code75 int Package::getSenderZIP() const76 {77 return senderZIP;78 } // end function getSenderZIP7980 // set recipient's name81 void Package::setRecipientName( const string &name )82 {83 recipientName = name;84 } // end function setRecipientName8586 // return recipient's name87 string Package::getRecipientName() const88 {89 return recipientName;90 } // end function getRecipientName9192 // set recipient's address93 void Package::setRecipientAddress( const string &address )94 {95 recipientAddress = address;96 } // end function setRecipientAddress97

Page 21: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 21

98 // return recipient's address99 string Package::getRecipientAddress() const100 {101 return recipientAddress;102 } // end function getRecipientAddress103104 // set recipient's city105 void Package::setRecipientCity( const string &city )106 {107 recipientCity = city;108 } // end function setRecipientCity109110 // return recipient's city111 string Package::getRecipientCity() const112 {113 return recipientCity;114 } // end function getRecipientCity115116 // set recipient's state117 void Package::setRecipientState( const string &state )118 {119 recipientState = state;120 } // end function setRecipientState121122 // return recipient's state123 string Package::getRecipientState() const124 {125 return recipientState;126 } // end function getRecipientState127128 // set recipient's ZIP code129 void Package::setRecipientZIP( int zip )130 {131 recipientZIP = zip;132 } // end function setRecipientZIP133134 // return recipient's ZIP code135 int Package::getRecipientZIP() const136 {137 return recipientZIP;138 } // end function getRecipientZIP139140 // validate and store weight141 void Package::setWeight( double w )142 {143 weight = ( w < 0.0 ) ? 0.0 : w;144 } // end function setWeight145146 // return weight of package147 double Package::getWeight() const148 {149 return weight;150 } // end function getWeight151

Page 22: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

22 Chapter 24 Object-Oriented Programming: Polymorphism

152 // validate and store cost per ounce153 void Package::setCostPerOunce( double cost )154 {155 costPerOunce = ( cost < 0.0 ) ? 0.0 : cost;156 } // end function setCostPerOunce157158 // return cost per ounce159 double Package::getCostPerOunce() const160 {161 return costPerOunce;162 } // end function getCostPerOunce163164 // calculate shipping cost for package165 double Package::calculateCost() const166 {167 return getWeight() * getCostPerOunce();168 } // end function calculateCost

1 // Exercise 24.11 Solution: TwoDayPackage.h2 // Definition of derived class TwoDayPackage.3 #ifndef TWODAY_H4 #define TWODAY_H56 #include "Package.h" // Package class definition78 class TwoDayPackage : public Package9 {

10 public:11 TwoDayPackage( const string &, const string &, const string &,12 const string &, int, const string &, const string &, const string &,13 const string &, int, double, double, double );1415 void setFlatFee( double ); // set flat fee for two-day-delivery service16 double getFlatFee() const; // return flat fee1718 virtual double calculateCost() const; // calculate shipping cost19 private:20 double flatFee; // flat fee for two-day-delivery service21 }; // end class TwoDayPackage2223 #endif

1 // Exercise 24.11 Solution: TwoDayPackage.cpp2 // Member-function definitions of class TwoDayPackage.34 #include "TwoDayPackage.h" // TwoDayPackage class definition56 // constructor7 TwoDayPackage::TwoDayPackage( const string &sName,8 const string &sAddress, const string &sCity, const string &sState,9 int sZIP, const string &rName, const string &rAddress,

10 const string &rCity, const string &rState, int rZIP,11 double w, double cost, double fee )

Page 23: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 23

12 : Package( sName, sAddress, sCity, sState, sZIP,13 rName, rAddress, rCity, rState, rZIP, w, cost )14 {15 setFlatFee( fee );16 } // end TwoDayPackage constructor1718 // set flat fee19 void TwoDayPackage::setFlatFee( double fee )20 {21 flatFee = ( fee < 0.0 ) ? 0.0 : fee;22 } // end function setFlatFee2324 // return flat fee25 double TwoDayPackage::getFlatFee() const26 {27 return flatFee;28 } // end function getFlatFee2930 // calculate shipping cost for package31 double TwoDayPackage::calculateCost() const32 {33 return Package::calculateCost() + getFlatFee();34 } // end function calculateCost

1 // Exercise 24.11 Solution: OvernightPackage.h2 // Definition of derived class OvernightPackage.3 #ifndef OVERNIGHT_H4 #define OVERNIGHT_H56 #include "Package.h" // Package class definition78 class OvernightPackage : public Package9 {

10 public:11 OvernightPackage( const string &, const string &, const string &,12 const string &, int, const string &, const string &, const string &,13 const string &, int, double, double, double );1415 void setOvernightFeePerOunce( double ); // set overnight fee16 double getOvernightFeePerOunce() const; // return overnight fee1718 virtual double calculateCost() const; // calculate shipping cost19 private:20 double overnightFeePerOunce; // fee per ounce for overnight delivery21 }; // end class OvernightPackage2223 #endif

1 // Exercise 24.11 Solution: OvernightPackage.cpp2 // Member-function definitions of class OvernightPackage.34 #include "OvernightPackage.h" // OvernightPackage class definition5

Page 24: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

24 Chapter 24 Object-Oriented Programming: Polymorphism

6 // constructor7 OvernightPackage::OvernightPackage( const string &sName,8 const string &sAddress, const string &sCity, const string &sState,9 int sZIP, const string &rName, const string &rAddress,

10 const string &rCity, const string &rState, int rZIP,11 double w, double cost, double fee )12 : Package( sName, sAddress, sCity, sState, sZIP,13 rName, rAddress, rCity, rState, rZIP, w, cost )14 {15 setOvernightFeePerOunce( fee ); // validate and store overnight fee16 } // end OvernightPackage constructor1718 // set overnight fee19 void OvernightPackage::setOvernightFeePerOunce( double overnightFee )20 {21 overnightFeePerOunce = ( overnightFee < 0.0 ) ? 0.0 : overnightFee;22 } // end function setOvernightFeePerOunce2324 // return overnight fee25 double OvernightPackage::getOvernightFeePerOunce() const26 {27 return overnightFeePerOunce;28 } // end function getOvernghtFeePerOunce2930 // calculate shipping cost for package31 double OvernightPackage::calculateCost() const32 {33 return getWeight() * ( getCostPerOunce() + getOvernightFeePerOunce() );34 } // end function calculateCost

1 // Exercise 24.11 Solution: ex24_11.cpp2 // Processing Packages polymorphically.3 #include <iostream>4 using std::cout;5 using std::endl;67 #include <iomanip>8 using std::setprecision;9 using std::fixed;

1011 #include <vector>12 using std::vector;1314 #include "Package.h" // Package class definition15 #include "TwoDayPackage.h" // TwoDayPackage class definition16 #include "OvernightPackage.h" // OvernightPackage class definition1718 int main()19 {20 // create vector packages21 vector < Package * > packages( 3 );22

Page 25: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 25

23 // initialize vector with Packages24 packages[ 0 ] = new Package( "Lou Brown", "1 Main St", "Boston", "MA",25 11111, "Mary Smith", "7 Elm St", "New York", "NY", 22222, 8.5, .5 );26 packages[ 1 ] = new TwoDayPackage( "Lisa Klein", "5 Broadway",27 "Somerville", "MA", 33333, "Bob George", "21 Pine Rd", "Cambridge",28 "MA", 44444, 10.5, .65, 2.0 );29 packages[ 2 ] = new OvernightPackage( "Ed Lewis", "2 Oak St", "Boston",30 "MA", 55555, "Don Kelly", "9 Main St", "Denver", "CO", 66666,31 12.25, .7, .25 );3233 double totalShippingCost = 0.0;3435 cout << fixed << setprecision( 2 );3637 // print each package's information and cost38 for ( size_t i = 0; i < packages.size(); i++ )39 {40 cout << "Package " << i + 1 << "\n\nSender:\n"41 << packages[ i ]->getSenderName() << '\n'42 << packages[ i ]->getSenderAddress() << '\n'43 << packages[ i ]->getSenderCity() << ", "44 << packages[ i ]->getSenderState() << ' '45 << packages[ i ]->getSenderZIP();46 cout << "\n\nRecipient:\n" << packages[ i ]->getRecipientName()47 << '\n' << packages[ i ]->getRecipientAddress() << '\n'48 << packages[ i ]->getRecipientCity() << ", "49 << packages[ i ]->getRecipientState() << ' '50 << packages[ i ]->getRecipientZIP();5152 double cost = packages[ i ]->calculateCost();53 cout << "\n\nCost: $" << cost << "\n\n";54 totalShippingCost += cost; // add this Package’s cost to total55 } // end for5657 cout << "Total shipping cost: $" << totalShippingCost << endl;58 return 0;59 } // end main

Page 26: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

26 Chapter 24 Object-Oriented Programming: Polymorphism

24.12 (Polymorphic Banking Program Using Account Hierarchy) Develop a polymorphic bankingprogram using the Account hierarchy created in Exercise 23.6. Create a vector of Account pointersto SavingsAccount and CheckingAccount objects. For each Account in the vector, allow the user tospecify an amount of money to withdraw from the Account using member function debit and anamount of money to deposit into the Account using member function credit. As you process eachAccount, determine its type. If an Account is a SavingsAccount, calculate the amount of interest

Package 1

Sender:Lou Brown1 Main StBoston, MA 11111

Recipient:Mary Smith7 Elm StNew York, NY 22222

Cost: $4.25

Package 2

Sender:Lisa Klein5 BroadwaySomerville, MA 33333

Recipient:Bob George21 Pine RdCambridge, MA 44444

Cost: $8.82

Package 3

Sender:Ed Lewis2 Oak StBoston, MA 55555

Recipient:Don Kelly9 Main StDenver, CO 66666

Cost: $11.64

Total shipping cost: $24.71

Page 27: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 27

owed to the Account using member function calculateInterest, then add the interest to the ac-count balance using member function credit. After processing an Account, print the updated ac-count balance obtained by invoking base class member function getBalance.

ANS: [Note: To achieve polymorphic behavior in the Account hierarchy, each class defini-tion must declare the debit and credit member functions as virtual functions.]

1 // Solution 24.12 Solution: Account.h2 // Definition of Account class.3 #ifndef ACCOUNT_H4 #define ACCOUNT_H56 class Account7 {8 public:9 Account( double ); // constructor initializes balance

10 virtual void credit( double ); // add an amount to the account balance11 virtual bool debit( double ); // subtract an amount from the balance12 void setBalance( double ); // sets the account balance13 double getBalance(); // return the account balance14 private:15 double balance; // data member that stores the balance16 }; // end class Account1718 #endif

1 // Exercise 24.12 Solution: Account.cpp2 // Member-function definitions for class Account.3 #include <iostream>4 using std::cout;5 using std::endl;67 #include "Account.h" // include definition of class Account89 // Account constructor initializes data member balance

10 Account::Account( double initialBalance )11 {12 // if initialBalance is greater than or equal to 0.0, set this value13 // as the balance of the Account14 if ( initialBalance >= 0.0 )15 balance = initialBalance;16 else // otherwise, output message and set balance to 0.017 {18 cout << "Error: Initial balance cannot be negative." << endl;19 balance = 0.0;20 } // end if...else21 } // end Account constructor2223 // credit (add) an amount to the account balance24 void Account::credit( double amount )25 {26 balance = balance + amount; // add amount to balance27 } // end function credit28

Page 28: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

28 Chapter 24 Object-Oriented Programming: Polymorphism

29 // debit (subtract) an amount from the account balance30 // return bool indicating whether money was debited31 bool Account::debit( double amount )32 {33 if ( amount > balance ) // debit amount exceeds balance34 {35 cout << "Debit amount exceeded account balance." << endl;36 return false;37 } // end if38 else // debit amount does not exceed balance39 {40 balance = balance - amount;41 return true;42 } // end else43 } // end function debit4445 // set the account balance46 void Account::setBalance( double newBalance )47 {48 balance = newBalance;49 } // end function setBalance5051 // return the account balance52 double Account::getBalance()53 {54 return balance;55 } // end function getBalance

1 // Exercise 24.12 Solution: SavingsAccount.h2 // Definition of SavingsAccount class.3 #ifndef SAVINGS_H4 #define SAVINGS_H56 #include "Account.h" // Account class definition78 class SavingsAccount : public Account9 {

10 public:11 // constructor initializes balance and interest rate12 SavingsAccount( double, double );1314 double calculateInterest(); // determine interest owed15 private:16 double interestRate; // interest rate (percentage) earned by account17 }; // end class SavingsAccount1819 #endif

1 // Exercise 22.16 Solution: SavingsAccount.cpp2 // Member-function definitions for class SavingsAccount.3

Page 29: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 29

4 #include "SavingsAccount.h" // SavingsAccount class definition56 // constructor initializes balance and interest rate7 SavingsAccount::SavingsAccount( double initialBalance, double rate )8 : Account( initialBalance ) // initialize base class9 {

10 interestRate = ( rate < 0.0 ) ? 0.0 : rate; // set interestRate11 } // end SavingsAccount constructor1213 // return the amount of interest earned14 double SavingsAccount::calculateInterest()15 {16 return getBalance() * interestRate;17 } // end function calculateInterest

1 // Exercise 24.12 Solution: CheckingAccount.h2 // Definition of CheckingAccount class.3 #ifndef CHECKING_H4 #define CHECKING_H56 #include "Account.h" // Account class definition78 class CheckingAccount : public Account9 {

10 public:11 // constructor initializes balance and transaction fee12 CheckingAccount( double, double );1314 virtual void credit( double ); // redefined credit function15 virtual bool debit( double ); // redefined debit function16 private:17 double transactionFee; // fee charged per transaction1819 // utility function to charge fee20 void chargeFee();21 }; // end class CheckingAccount2223 #endif

1 // Exercise 24.12 Solution: CheckingAccount.cpp2 // Member-function definitions for class CheckingAccount.3 #include <iostream>4 using std::cout;5 using std::endl;67 #include "CheckingAccount.h" // CheckingAccount class definition89 // constructor initializes balance and transaction fee

10 CheckingAccount::CheckingAccount( double initialBalance, double fee )11 : Account( initialBalance ) // initialize base class12 {

Page 30: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

30 Chapter 24 Object-Oriented Programming: Polymorphism

13 transactionFee = ( fee < 0.0 ) ? 0.0 : fee; // set transaction fee14 } // end CheckingAccount constructor1516 // credit (add) an amount to the account balance and charge fee17 void CheckingAccount::credit( double amount )18 {19 Account::credit( amount ); // always succeeds20 chargeFee();21 } // end function credit2223 // debit (subtract) an amount from the account balance and charge fee24 bool CheckingAccount::debit( double amount )25 {26 bool success = Account::debit( amount ); // attempt to debit2728 if ( success ) // if money was debited, charge fee and return true29 {30 chargeFee();31 return true;32 } // end if33 else // otherwise, do not charge fee and return false34 return false;35 } // end function debit3637 // subtract transaction fee38 void CheckingAccount::chargeFee()39 {40 Account::setBalance( getBalance() - transactionFee );41 cout << "$" << transactionFee << " transaction fee charged." << endl;42 } // end function chargeFee

1 // Exercise 24.12 Solution: ex24_16.cpp2 // Processing Accounts polymorphically.3 #include <iostream>4 using std::cout;5 using std::cin;6 using std::endl;78 #include <iomanip>9 using std::setprecision;

10 using std::fixed;1112 #include <vector>13 using std::vector;1415 #include "Account.h" // Account class definition16 #include "SavingsAccount.h" // SavingsAccount class definition17 #include "CheckingAccount.h" // CheckingAccount class definition1819 int main()20 {21 // create vector accounts22 vector < Account * > accounts( 4 );

Page 31: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

Exercises 31

2324 // initialize vector with Accounts25 accounts[ 0 ] = new SavingsAccount( 25.0, .03 );26 accounts[ 1 ] = new CheckingAccount( 80.0, 1.0 );27 accounts[ 2 ] = new SavingsAccount( 200.0, .015 );28 accounts[ 3 ] = new CheckingAccount( 400.0, .5 );2930 cout << fixed << setprecision( 2 );3132 // loop through vector, prompting user for debit and credit amounts33 for ( size_t i = 0; i < accounts.size(); i++ )34 {35 cout << "Account " << i + 1 << " balance: $"36 << accounts[ i ]->getBalance();3738 double withdrawalAmount = 0.0;39 cout << "\nEnter an amount to withdraw from Account " << i + 140 << ": ";41 cin >> withdrawalAmount;42 accounts[ i ]->debit( withdrawalAmount ); // attempt to debit4344 double depositAmount = 0.0;45 cout << "Enter an amount to deposit into Account " << i + 146 << ": ";47 cin >> depositAmount;48 accounts[ i ]->credit( depositAmount ); // credit amount to Account4950 // downcast pointer51 SavingsAccount *savingsAccountPtr =52 dynamic_cast < SavingsAccount * > ( accounts[ i ] );5354 // if Account is a SavingsAccount, calculate and add interest55 if ( savingsAccountPtr != 0 )56 {57 double interestEarned = savingsAccountPtr->calculateInterest();58 cout << "Adding $" << interestEarned << " interest to Account "59 << i + 1 << " (a SavingsAccount)" << endl;60 savingsAccountPtr->credit( interestEarned );61 } // end if6263 cout << "Updated Account " << i + 1 << " balance: $"64 << accounts[ i ]->getBalance() << "\n\n";65 } // end for6667 return 0;68 } // end main

Page 32: Object Oriented Programming Polymorphismfaculty.salisbury.edu/~xswang/Courses/csc220/Document/CHTP5e-PI… · Object-Oriented Programming: Polymorphism ... 24.10 (Payroll System ...

32 Chapter 24 Object-Oriented Programming: Polymorphism

Account 1 balance: $25.00Enter an amount to withdraw from Account 1: 15.00Enter an amount to deposit into Account 1: 10.50Adding $0.61 interest to Account 1 (a SavingsAccount)Updated Account 1 balance: $21.11

Account 2 balance: $80.00Enter an amount to withdraw from Account 2: 90.00Debit amount exceeded account balance.Enter an amount to deposit into Account 2: 45.00$1.00 transaction fee charged.Updated Account 2 balance: $124.00

Account 3 balance: $200.00Enter an amount to withdraw from Account 3: 75.50Enter an amount to deposit into Account 3: 300.00Adding $6.37 interest to Account 3 (a SavingsAccount)Updated Account 3 balance: $430.87

Account 4 balance: $400.00Enter an amount to withdraw from Account 4: 56.81$0.50 transaction fee charged.Enter an amount to deposit into Account 4: 37.83$0.50 transaction fee charged.Updated Account 4 balance: $380.02


Recommended