Polymorphism(多态)
Ex 1:(Employee类继承层次)
Description of the Problem
英文:(Payroll System Modification)
Modify the payroll system of Figs. 13.13~13.23 to include private
data member birthDate in class Employee.
Use class Date from Figs. 11.12~11.13 to represent an employee’s birthday. Assume that payroll is processed once per month. Create a vector of Employee references to store the various employee objects. In a loop, calculate the payroll for each Employee (polymorphically), and add a $100.00 bonus to the person’s payroll amount if the current month is the month in which the Employee’s birthday occurs.
中文:修改本章的的工资系统,增加private数据成员birthDate(Date对象), 要求使用第11章的Date作为生日类型。假设工资系统每月处理一次,创建一个vector存储Employee指针来存储不同的员工对象,用一个循环计算每个员工的工资(多态),遇到当月过生日的员工多发100美元奖金。
Problem-Solving Tips
1)取当前时间函数提示:
方法一:
#include<windows.h>
int main()
{
SYSTEMTIME systm;
GetLocalTime(&systm);
cout<<systm.wYear<<"-"<<systm.wMonth<<"-"<<systm.wDay<<""<< systm.wHour<<":"<<systm.wMinute<<":"<<systm.wSecond;
return 0;
}
方法二:
#include
#include
using namespace std;
int main()
{
time_t nowtime;
struct tm* ptm;
time(&nowtime);
ptm = localtime(&nowtime);
cout<tm_year +1900<<"-"<tm_mon +1<<"-"<tm_mday<<" “<tm_hour<<”:"<tm_min<<":"<tm_sec;
return 0;
}
2)测试函数示例
参考教材的测试函数13.23和13.25。
结果示例
【我的代码】
\\Date.h
#ifndef BIRTH_H
#define BIRTH_H
#include<iostream>
using namespace std;
class Date
{
public:
Date(int mn,int dy,int yr)
{
if(mn>0&&mn<13)
month=mn;
else
{
month=0;
cout<<"Invalid month ("<<mn<<") set to 1.\n";
}
year=yr;
day=checkDay(dy);
}
~Date(){}
int getMonth() const
{
return month;
}
void print() const
{
cout<<"birthday: ";
switch(month)
{
case 1:cout<<"January "<<day<<","<<year;break;
case 2:cout<<"February "<<day<<","<<year;break;
case 3:cout<<"March "<<day<<","<<year;break;
case 4:cout<<"April "<<day<<","<<year;break;
case 5:cout<<"May "<<day<<","<<year;break;
case 6:cout<<"June "<<day<<","<<year;break;
case 7:cout<<"July "<<day<<","<<year;break;
case 8:cout<<"August "<<day<<","<<year;break;
case 9:cout<<"September "<<day<<","<<year;break;
case 10:cout<<"October "<<day<<","<<year;break;
case 11:cout<<"November "<<day<<","<<year;break;
case 12:cout<<"December "<<day<<","<<year;break;
default:cout<<"wrong date";
}
}
int checkDay(int d)
{
static int daysPerMonth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if(d>0&&d<=daysPerMonth[month-1])
return d;
if(month==2&&d==29&&(year%400==0||(year%4==0&&year%100!=0)))
return d;
else
{
return 0;
cout<<"Invalid day for current month and day"<<endl;
}
}
private:
int month,day,year;
};
#endif
\\Employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include<string>
#include<iostream>
#include<windows.h>
#include"Date.h"
using namespace std;
class Employee
{
public:
Employee(const string &first,const string &last,const string &ssn,const Date &dateOfBirth)
:firstName(first),lastName(last),socialSecurityNumber(ssn),birthDate(dateOfBirth)
{
}
virtual ~Employee()
{
cout<<"deleting object of class "<<typeid(*this).name()<<endl;
}
void setFirstName(const string &first)
{
firstName=first;
}
string getFirstName()const
{
return firstName;
}
void setLastName(const string &last)
{
lastName=last;
}
string getLastName()const
{
return lastName;
}
void setSocialSecurityNumber(const string &ssn)
{
socialSecurityNumber=ssn;
}
string getSocialSecurityNumber()const
{
return socialSecurityNumber;
}
virtual double earnings() const = 0;
bool checkBirthday() const
{
SYSTEMTIME systm;
GetLocalTime(&systm);
if(systm.wMonth==birthDate.getMonth())
return 1;
else
return 0;
}
virtual void print() const
{
cout<<getFirstName()<<" "<<getLastName()<<endl;
birthDate.print();
cout<<"\nsocial security number: "<<getSocialSecurityNumber();
}
private:
string firstName;
string lastName;
string socialSecurityNumber;
Date birthDate;
};
#endif
\\SalariedEmployee.h
#ifndef SALARIEDEMPLOYEE_H
#define SALARIEDEMPLOYEE_H
#include"Employee.h"
#include<iostream>
#include<stdexcept>
#include<string>
using namespace std;
class SalariedEmployee:public Employee
{
public:
SalariedEmployee::SalariedEmployee(const string &first,const string &last,
const string &ssn,const Date &dateOfBirth,double salary=0.0)
:Employee(first,last,ssn,dateOfBirth)
{
setWeeklySalary(salary);
}
virtual ~SalariedEmployee()
{
cout<<"deleting object of class "<<typeid(*this).name()<<endl;
}
void setWeeklySalary(double s)
{
if(s>=0.0)
weeklySalary=s;
else
throw invalid_argument("Weekly salary must be >=0.0");
}
double getWeeklySalary()const
{
return weeklySalary;
}
double earnings() const
{
if(checkBirthday())
{
cout<<"\nHAPPY BIRTHDAY!";
return getWeeklySalary()+100;
}
else
return getWeeklySalary();
}
void print() const
{
cout<<"salaried employee: ";
Employee::print();
cout<<"\nweekly salary: "<<getWeeklySalary();
}
private:
double weeklySalary;
};
#endif
\\HourlyEmployee.h
#ifndef HOURLYEMPLOYEE_H
#define HOURLYEMPLOYEE_H
#include<iostream>
#include<stdexcept>
#include"Employee.h"
using namespace std;
class HourlyEmployee:public Employee
{
public:
HourlyEmployee(const string &first,const string &last,
const string &ssn,const Date &dateOfBirth,double wage=0.0,double hours=0.0)
:Employee(first,last,ssn,dateOfBirth)
{
setHourlySalary(wage);
setHours(hours);
}
virtual ~HourlyEmployee()
{
cout<<"deleting object of class "<<typeid(*this).name()<<endl;
}
void setHourlySalary(double s)
{
if(s>=0.0)
wage=s;
else
throw invalid_argument("Hourly salary must be >=0.0");
}
double getHourlySalary()const
{
return wage;
}
void setHours(double s)
{
if(s>=0.0)
hours=s;
else
throw invalid_argument("Hours must be >=0.0");
}
double getHours()const
{
return hours;
}
double earnings() const
{
if(checkBirthday())
{
cout<<"\nHAPPY BIRTHDAY!";
if(hours<=40)
return wage*hours+100;
else
return (40*wage)+((hours-40)*wage*1.5)+100;
}
else
{
if(hours<=40)
return wage*hours;
else
return (40*wage)+((hours-40)*wage*1.5);
}
}
void print() const
{
cout<<"hourly employee: ";
Employee::print();
cout<<"\nhourly wage: "<<getHourlySalary()<<"; hours worked: "<<getHours();
}
private:
double wage;
double hours;
};
#endif
\\CommissionEmployee.h
#ifndef COMMISSIONEMPLOYEE_H
#define COMMISSIONEMPLOYEE_H
#include<iostream>
#include<stdexcept>
#include<string>
#include"Employee.h"
using namespace std;
class CommissionEmployee:public Employee
{
public:
CommissionEmployee(const string &first,const string &last,
const string &ssn,const Date &dateOfBirth,double sales=0.0,double rate=0.0)
:Employee(first,last,ssn,dateOfBirth)
{
setGrossSales(sales);
setCommissionRate(rate);
}
virtual ~CommissionEmployee()
{
cout<<"deleting object of class "<<typeid(*this).name()<<endl;
}
void setCommissionRate(double r)
{
if(r>0.0&&r<1.0)
commissionRate=r;
else
throw invalid_argument("Commission rate must be >0.0 and <1.0");
}
double getCommissionRate()const
{
return commissionRate;
}
void setGrossSales(double s)
{
if(s>=0.0)
grossSales=s;
else
throw invalid_argument("Gross salary must be >=0.0");
}
double getGrossSales() const
{
return grossSales;
}
double earnings() const
{
if(checkBirthday())
{
cout<<"\nHAPPY BIRTHDAY!";
return getCommissionRate()*getGrossSales()+100;
}
else
return getCommissionRate()*getGrossSales();
}
void print() const
{
cout<<"commission employee: ";
Employee::print();
cout<<"\ngross sales: "<<getGrossSales()
<<"; commission rate: "<<getCommissionRate();
}
private:
double grossSales;
double commissionRate;
};
#endif
\\BasePlusCommissionEmployee.h
#ifndef BASEPLUSCOMMISSIONEMPLOYEE_H
#define BASEPLUSCOMMISSIONEMPLOYEE_H
#include<string>
#include<iostream>
#include<stdexcept>
#include"CommissionEmployee.h"
using namespace std;
class BasePlusCommissionEmployee:public CommissionEmployee
{
public:
BasePlusCommissionEmployee::BasePlusCommissionEmployee(const string &first,const string &last,
const string &ssn,const Date &dateOfBirth,double sales=0.0,double rate=0.0,double salary=0.0)
:CommissionEmployee(first,last,ssn,dateOfBirth,sales,rate)
{
setBaseSalary(salary);
}
virtual ~BasePlusCommissionEmployee()
{
cout<<"deleting object of class "<<typeid(*this).name()<<endl;
}
void setBaseSalary(double s)
{
if(s>=0.0)
baseSalary=s;
else
throw invalid_argument("Salary must be >=0.0");
}
double getBaseSalary()const
{
return baseSalary;
}
double earnings() const
{
return getBaseSalary()+CommissionEmployee::earnings();
}
void print() const
{
cout<<"base-salaried ";
CommissionEmployee::print();
cout<<"; base salary: "<<getBaseSalary();
}
private:
double baseSalary;
};
#endif
\\Employee.cpp
#include<iostream>
#include<iomanip>
#include<vector>
#include"Employee.h"
#include"Date.h"
#include"SalariedEmployee.h"
#include"HourlyEmployee.h"
#include"CommissionEmployee.h"
#include"BasePlusCommissionEmployee.h"
void virtualViaPointer( const Employee *const );
void virtualViaReference( const Employee &);
using namespace std;
int main()
{
cout<<fixed<<setprecision( 2 );
Date birth1(6,15,1944);
Date birth2(5,29,1960);
Date birth3(9,8,1954);
Date birth4(3,2,1965);
SalariedEmployee salariedEmployee(
"John","Smith","111-11-1111",birth1,800);
HourlyEmployee hourlyEmployee(
"Karen","Price","222-22-2222",birth2,16.75, 40 );
CommissionEmployee commissionEmployee(
"Sue","Jones","333-33-3333",birth3,10000.00,0.06 );
BasePlusCommissionEmployee basePlusCommissionEmployee(
"Bob", "Lewis", "444-44-4444",birth4, 5000.00, 0.04, 300 );
vector <Employee*> employees( 4 );
employees[ 0 ] = &salariedEmployee;
employees[ 1 ] = &hourlyEmployee;
employees[ 2 ] = &commissionEmployee;
employees[ 3 ] = &basePlusCommissionEmployee;
cout << "Employees processed polymorphically via dynamic binding:\n\n";
for ( size_t i = 0; i < employees.size(); i++ )
virtualViaPointer(employees[ i ]);
for ( size_t i = 0; i < employees.size(); i++ )
virtualViaReference(*employees[ i ]);
system("pause");
return 0;
}
void virtualViaPointer(const Employee *const A)
{
A->print();
cout<< "\nearned $" <<A->earnings()<< "\n\n";
}
void virtualViaReference(const Employee &A)
{
A.~Employee();
}
Ex 2:(班级学生的成绩管理)
Description of the Problem:
Complete the abstract class called “Person”.
Define a concrete class called “Student” inherited from “Person” class. Complete the class “Class” and make the following
function named “main” can output correctly.
class Class(此类需要补充完整)
{
public:
Class (int s=0 ):size(s)
{
pps=new Person*[s];
}
private:
int size;
Person** pps;
};
void main()
{
Class class1(3);
class1[0]= new Student(1,100);
class1[1]= new Student(2,90);
class1[2]= new Student(3,80);
class1.output();
system("pause");
}
输出示例:
【我的代码】
\\Person.h
#ifndef PERSON_H
#define PERSON_H
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person(int name)
{
id=name;
}
~Person(){}
virtual void output() const
{
cout<<"Student id="<<id<<" ";
}
private:
int id;
};
#endif
\\Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include<iostream>
#include<iomanip>
#include"Person.h"
using namespace std;
class Student:public Person
{
public:
Student(int id,int grade):Person(id)
{
score=grade;
}
~Student(){}
void output()const
{
Person::output();
cout<<"score="<<score<<endl;
}
private:
int score;
};
#endif
\\班级学生的成绩管理.cpp
#include<iostream>
#include"Person.h"
#include"Student.h"
using namespace std;
class Class
{
public:
Class (int s=0 ):size(s)
{
pps=new Person*[s];
}
~Class(){}
Person* &operator[](int i)
{
return pps[i];
}
void output()
{
for (int i=0;i<size;i++)
pps[i]->output();
}
private:
int size;
Person** pps;
};
void main()
{
Class class1(3);
class1[0]= new Student(1,100);
class1[1]= new Student(2,90);
class1[2]= new Student(3,80);
class1.output();
system("pause");
}