<center> 浙江理工大学信息学院 </center> <center> 实验指导书 </center> <center> 实验名称:类的多态性的实现 学时安排:3 </center> <center> 实验类别:设计性实验 实验要求:1人1组 </center> <center> 学号: 2018329621200 姓名:申屠志刚 </center> <center>  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ </center>

一、实验目的
1.理解重载运算符的意义。
2.掌握使用成员函数、友员函数重载运算符的特点。
3.掌握重载运算符函数的调用方法。
4.掌握动态联编的概念。
5.掌握虚函数和纯虚函数的使用方法。
二、实验原理介绍
设计性实验
具体原理请见实验内容和步骤
实现对抽象类的继承,通过operator函数调用的形式,实现运算符的重载
三、实验设备介绍
软件需求: windows或linux下的c++编译器
硬件需求: 对于硬件方面的要求,建议配置是Pentium III 450以上的CPU处理器,64MB以上的内存,200MB的自由硬盘空间、CD-ROM驱动器、能支持24位真彩色的显示卡、彩色显示器、打印机。
四、实验内容
某公司的员工有经理Manager、技术人员Technicist和营销人员SalsePerson,他们的薪金计算方法如下:
经理按月计酬,方法是:基本工资+奖金;技术人员按月计酬,方法是:基本工资;营销人员按月计酬,方法是:基本工资+销售利润*5%。
每类人员都有职工编号、姓名、性别、入职时间、职位、基本工资等数据,其中为入职时间定义CDate类,并为该类重载运算符<<,实现入职时间的输出;各类人员使用统一接口get_pay()计算各类人员的月薪。其次,设计一个统计并输出该公司每个人员某几个月薪金情况的报表类Report,该类提供insert接口向Report类的容器中添加员工信息,并提供print接口用于输出每个员工的职工编号、姓名、性别、入职时间、职位和在设定的月份时间段中该员工的薪酬总额。为了方便实现查找功能,为Report类重载[]运算符的功能,下标值为职位,能根据职位信息查找出所有符合该职位的员工,并重载print接口,输出查找出的员工信息,信息包括职工编号、姓名、性别、入职时间、职位、基本工资。在主函数中对实现的类进行测试,首先,创建各类人员对象,通过Report类的insert接口向报表中添加这些人员信息,然后通过Report类的print接口输出报表。其次测试报表的查找功能,输入要查找的员工职位信息,通过Report类的print接口输出查找到的员工基本信息报表。
五、注意事项和要求
要求学生要提前准备实验的内容
实验完成后要求写出实验报告
六、参考书目
【C++ Prime题解】侯捷译 华中科技大学出版社
【C++程序设计与应用】 张耀仁著 华中科技大学出版社

<center> 浙江理工大学信息学院 </center> <center> 实验指导书 </center> <center> 实验名称:类的多态性的实现 学时安排:3 </center> <center> 实验类别:设计性实验 实验要求:1人1组 </center> <center> 学号: 2018329621200 姓名:申屠志刚 </center> <center>  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ </center>

一、实验目的
1.理解重载运算符的意义。
2.掌握使用成员函数、友员函数重载运算符的特点。
3.掌握重载运算符函数的调用方法。
4.掌握动态联编的概念。
5.掌握虚函数和纯虚函数的使用方法。
二、实验原理介绍
设计性实验
具体原理请见实验内容和步骤
实现对抽象类的继承,通过operator函数调用的形式,实现运算符的重载
三、实验设备介绍
软件需求: windows或linux下的c++编译器
硬件需求: 对于硬件方面的要求,建议配置是Pentium III 450以上的CPU处理器,64MB以上的内存,200MB的自由硬盘空间、CD-ROM驱动器、能支持24位真彩色的显示卡、彩色显示器、打印机。
四、实验内容
某公司的员工有经理Manager、技术人员Technicist和营销人员SalsePerson,他们的薪金计算方法如下:
经理按月计酬,方法是:基本工资+奖金;技术人员按月计酬,方法是:基本工资;营销人员按月计酬,方法是:基本工资+销售利润*5%。
每类人员都有职工编号、姓名、性别、入职时间、职位、基本工资等数据;各类人员使用统一接口get_pay()计算各类人员的月薪,重载<<运算符实现员工信息的输出。其次,设计一个统计并输出该公司员工当月薪金情况的报表类Report,该类提供insert接口向Report类的容器中添加员工信息,并提供print接口用于展示以职位为单位的每个员工的职工编号、姓名、性别、入职时间以及当月该员工的薪酬,并统计出该职位员工薪酬的最高值和最低值。为了提供更方便的查找功能,请为Report类重载[]运算符,下标值为职位,能根据职位信息查找出所有符合该职位的员工。在主函数中对实现的类进行测试,首先,创建各类人员对象,通过Report类的insert接口向报表中添加这些人员信息,然后通过Report类的print接口输出当月员工薪酬情况报表。存储员工对象的容器请选用合适的STL容器。
五 程序清单
date.h

#pragma once
#include <iostream>
#include<cstdlib>
#include<string>
#include<cstdio>
#include<ctime>
using namespace std;
class CDate{
	int d,m,y;
	static const string df_s;
	static const string df_l;
	static CDate *default_date;
public:
	CDate(int dd,int mm,int yy);
	CDate();
	void add_year(int n);
	void add_month(int n);
	void add_day(int n);
	string format(string df);
	int get_day() const;
	int get_month() const;
	int get_year() const;
	static void set_default(int,int,int);
	friend ostream& operator<<(ostream &os,CDate d);
};

date.cpp

#include "date.h"
CDate::CDate(int dd, int mm, int yy)    //初始化
{
    if((mm>=1 && mm<=12) && (dd>=1 && dd<=31))
    {
        m = mm; d = dd; y = yy;
    }else {
        m = 0; d = 0; y = 0;
        cout << "the date created is wrong" << endl;
    }
}
CDate::CDate()     //初始化
{
    if(default_date != 0){
        d = default_date -> d;
        m = default_date -> m;
        y = default_date -> y;
    }
    else
    {
        time_t now;
        time(&now);
        struct tm *t_now;
        t_now = localtime(&now);
        y = t_now -> tm_year + 1900;
        m = t_now -> tm_mon + 1;
        d = t_now -> tm_mday;
    }
}
void CDate::add_year(int n)               //加n年
{
    y += n;
}
void CDate::add_month(int n)              //加n月
{
    m += n;
}
void CDate::add_day(int n)                //加n天
{
    d += n;
}
string CDate::format(string df)
{
    char c_df[20];
    if(df == df_s)
    {
        sprintf(c_df, "%d-%d-%d", y, m, d);
        return string(c_df);
    }
    if(df == df_l)
    {
        sprintf(c_df, "%d年%d月%d日", y, m, d);
        return string(c_df);
    }
    return string("");
}
int CDate::get_year() const
{
    return y;
}
int CDate::get_month() const
{
    return m;
}
int CDate::get_day() const
{
    return d;
}
CDate *CDate::default_date = 0;
const string CDate::df_s = "ddd";
const string CDate::df_l = "DDD";
void CDate::set_default(int d, int m, int y){
     CDate::default_date = new CDate(d,m,y);
}
ostream& operator<<(ostream &os,CDate d)
{
   os<<d.format("DDD");
   return os;
}

Employee.h

#pragma once
#include<string>
#include<map>
#include<iostream>
#include <iomanip>
#include"date.h"
using namespace std;
class Employee
{
protected:
	string name,id;
	int gender;
	CDate enroll_date;
	string job;
	int salary;
public:
	Employee(string ID,string Name,int Gender,CDate Enroll_date,string Job,int Salary);
	void set_salary(int salary){this->salary = salary;}
	void set_job(string job){this->job = job;}
	void set_enroll(CDate enroll){this->enroll_date = enroll;}
	string get_id(){return id;}
	string get_name(){return name;}
	CDate get_enroll(){return enroll_date;}
	int get_gender(){return gender;}
	string get_job(){return job;}
	int get_salary(){return salary;}
	virtual double get_pay(int m) = 0;
	friend ostream &operator<<(ostream &output,const Employee &a1);
};
class Manager:public Employee{
	map<int,int> bonus;
public:
	Manager(string id,string name,int gender,CDate enroll,string  job,int salary);
	Manager(string id,string name,int gender,CDate enroll,string  job,int salary,map<int,int> bonus);
	void set_bonus(map<int,int> bonus);
	virtual double get_pay(int m);
};
class Technicist:public Employee{
public:
	Technicist(string id,string name,int gender,CDate enroll,string  job,int salary);
	virtual double get_pay(int m);
};
class SalesPerson:public Employee{
private:
	map<int,int> sales;
public:
	SalesPerson(string id,string name,int gender,CDate enroll,string  job,int salary);
	SalesPerson(string id,string name,int gender,CDate enroll,string  job,int salary,map<int,int> sales);
	void set_sales(map<int,int> sales);
	virtual double get_pay(int m);
};

Employee.cpp

#include<iostream>
#include "Employee.h"
using namespace std;

ostream &operator<<(ostream &output,const Employee &a)	{
 	output<<a.id<<"\t"<<a.name<<"\t"<<(a.gender?"男":"女")<<"\t"<<a.enroll_date<<"\t"<<a.job<<"\t"<<a.salary;
	return output;
}

Employee::Employee(string ID,string Name,int Gender,CDate Enroll_date,string  Job,int Salary){
	id=ID;
	name=Name;
	gender=Gender;
	enroll_date=Enroll_date;
	salary=Salary;
    job=Job;
}
Manager::Manager(string id,string name,int gender,CDate enroll,string job,int salary):Employee(id,name,gender,enroll,job,salary){}
Manager::Manager(string id,string name,int gender,CDate enroll,string job,int salary,map<int,int> bonus):Employee(id,name,gender,enroll,job,salary),bonus(bonus){}
double Manager::get_pay(int m){return bonus[m]+get_salary();}
Technicist::Technicist(string id,string name,int gender,CDate enroll,string  job,int salary):Employee(id,name,gender,enroll,job,salary){}
double Technicist::get_pay(int m){return get_salary();}
SalesPerson::SalesPerson(string id,string name,int gender,CDate enroll,string  job,int salary):Employee(id,name,gender,enroll,job,salary){}
SalesPerson::SalesPerson(string id,string name,int gender,CDate enroll,string  job,int salary,map<int,int> sales):Employee(id,name,gender,enroll,job,salary),sales(sales){}
double SalesPerson::get_pay(int m){return sales[m]*0.05+get_salary();}

Report.h

#include"Employee.h"
#include<vector>
#include<list>
#include<iostream>
#include<algorithm>
using namespace std;
class Report
{
private:
	vector<Employee*> members;
	list<Employee*> operator[](string job);
	double min_pay(list<Employee*> emp_list, int month);
	double max_pay(list<Employee*> emp_list, int month);
	void print(list<Employee*> emp_list,int month);
public:
	~Report();
	void insert(Employee* member);
	void print(int rp_mon);
};

Report.cpp

#include "Report.h"
Report::~Report(){

}
list<Employee*> Report::operator[](string  job){
    list<Employee*> L;
	for(vector<Employee*>::iterator iter1=members.begin();iter1!=members.end();iter1++){
		if((*iter1)->get_job()==job){
			L.push_back(*iter1);
		}
	}
	return L;
}
double Report::min_pay(list<Employee*> emp_list, int month){
    list<double>Payment;
	for(list<Employee*>::iterator iter3=emp_list.begin();iter3!=emp_list.end();iter3++){
		Payment.push_back((*iter3)->get_pay(month));
	}
	return *min_element(Payment.begin(),Payment.end());
}
double Report::max_pay(list<Employee*> emp_list, int month){
    list<double>Payment;
	for(list<Employee*>::iterator iter3=emp_list.begin();iter3!=emp_list.end();iter3++){
		Payment.push_back((*iter3)->get_pay(month));
	}
	return *max_element(Payment.begin(),Payment.end());
}
void Report::print(list<Employee*> emp_list,int month){
	for(list<Employee*>::iterator iter2=emp_list.begin();iter2!=emp_list.end();iter2++){
        cout<<(*(*iter2))<<"\t"<<(*iter2)->get_pay(month)<<endl;
	}
}

void Report::insert(Employee* member){
    members.push_back(member);
}
void Report::print(int rp_mon){
    cout<<" 第"<<rp_mon<<"月职工收入报表 "<<endl;
	list<Employee*>empl;
	string Position[3]={"经理","技术","销售"};
	for(int i=0;i<3;i++){
        cout<<"------------------------------------------------------------------------"<<endl;
        cout<<"职位:"<<Position[i]<<endl;
        cout<<"工号\t"<<"姓名\t"<<"性别\t"<<"入职时间\t"<<"职位\t"<<"基本工资\t"<<"奖金"<<endl;
        empl=(*this)[Position[i]];
        print(empl,rp_mon);
        cout<<"Max payment: "<<max_pay(empl,rp_mon)<<endl;
        cout<<"Min payment: "<<min_pay(empl,rp_mon)<<endl<<endl;
	}
}

main.cpp

/* *@Author: STZG *@Language: C++ */
#include<iostream>
#include "employee.h"
#include "report.h"
#include "date.h"
using namespace std;
int main()
{
    Report AA;
	AA.insert(new Manager("001","Tom",1,CDate(11,8,2001),"经理",2000,
                        map<int,int>{{1,1000},{2,2000},{3,3000},{4,3000},{5,2500},{6,4000},
                                    {7,7000},{8,8000},{9,3000},{10,1050},{11,10000},{12,6000}}));
	AA.insert(new Manager("002","Ann",0,CDate(23,5,2013),"经理",3000,
                        map<int,int>{{1,1000},{2,2000},{3,3000},{4,3000},{5,2500},{6,4000},
                                    {7,7000},{8,8000},{9,3000},{10,1050},{11,10000},{12,6000}}));
	AA.insert(new Manager("003","Jim",1,CDate(16,7,1998),"经理",3000,
                        map<int,int>{{1,1000},{2,2000},{3,3000},{4,3000},{5,2500},{6,4000},
                                    {7,7000},{8,8000},{9,3000},{10,1050},{11,10000},{12,6000}}));
	AA.insert(new Technicist("004","David",0,CDate(14,12,2009),"技术",2000));
	AA.insert(new Technicist("005","Tina",1,CDate(26,8,2015),"技术",1500));
	AA.insert(new Technicist("006","John",1,CDate(18,1,1999),"技术",3000));
	AA.insert(new SalesPerson("007","Helen",0,CDate(4,2,2000),"销售",2000,
                            map<int,int>{{1,1000},{2,8000},{3,1000},{4,9000},{5,1000},{6,1000},
                                    {7,1000},{8,1000},{9,1000},{10,2000},{11,1000},{12,1000}}));
	AA.insert(new SalesPerson("008","Lily",0,CDate(30,11,2007),"销售",1000,
                            map<int,int>{{1,1000},{2,2000},{3,3000},{4,3000},{5,2500},{6,4000},
                                    {7,7000},{8,8000},{9,3000},{10,1050},{11,10000},{12,6000}}));
	AA.insert(new SalesPerson("009","Tony",1,CDate(1,8,2013),"销售",1500,
                            map<int,int>{{1,1000},{2,1000},{3,3000},{4,1000},{5,1000},{6,1000},
                                    {7,1000},{8,1000},{9,1000},{10,1000},{11,1000},{12,1000}}));
	int month;
	cout<<"请输入生成报表的月份"<<endl;
	cin>>month;
	AA.print(month);
	//cout << "Hello world!" << endl
    return 0;
}

六 运行结果

七 实验心得
1.理解重载运算符的意义。
2.掌握使用成员函数、友员函数重载运算符的特点。
3.掌握重载运算符函数的调用方法。
4.掌握动态联编的概念。
5.掌握虚函数和纯虚函数的使用方法。