一、实验目的
1.理解重载运算符的意义。
2.掌握使用成员函数、友员函数重载运算符的特点。
3.掌握重载运算符函数的调用方法。
4.掌握动态联编的概念。
5.掌握虚函数和纯虚函数的使用方法。
二、实验原理介绍
设计性实验
具体原理请见实验内容和步骤
实现对抽象类的继承,通过operator函数调用的形式,实现运算符的重载
三、实验设备介绍
软件需求: 支持C++程序编辑、编译和运行的软件
硬件需求: 处理器i3、内存2G以上计算机一台。
四、实验内容
某公司的员工有经理Manager、技术人员Technicist和营销人员SalsePerson,他们的薪金计算方法如下:
经理按月计酬,方法是:基本工资+奖金;技术人员按月计酬,方法是:基本工资;营销人员按月计酬,方法是:基本工资+销售利润*5%。其中基本工资为8000元再加上工龄工资。工龄工资就是雇员在该公司工作的工龄每增加一年,月工资就增加200元。
每类人员都有职工编号、姓名、性别、入职时间、职位、基本工资等数据;各类人员使用统一接口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 { private: 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" #pragma warning( disable : 4996 ) 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: #ifndef CLASS_H_INCLUDED #define CLASS_H_INCLUDED #include<windows.h> #include<iostream> #include<string> #include<list> #include<vector> #include<map> #include "date.h" using namespace std; class Employee { protected: string name; string ID; string sex; string job; CDate date; double basicmoney; public: Employee(string ID, string name, string sex, CDate date, string job, double basicmoney); string getjob() { return job; } string getname() { return name; } string getID() { return ID; } string getsex() { return sex; } double getbasicmoney() { return basicmoney; } CDate getdate() { return date; } virtual double getpay(int m) = 0; }; class Manager :public Employee { private: map<int, int> price; public: Manager(string ID, string name, string sex, CDate date, string job, double basicmoney, map<int, int>price) :Employee(ID, name, sex, date, job, basicmoney) { this->price = price; } double getpay(int m); }; class Technicist :public Employee { public: Technicist(string ID, string name, string sex, CDate date, string job, double basicmoney) :Employee(ID, name, sex, date, job, basicmoney) {} double getpay(int m); }; class SalesPerson :public Employee { private: map<int, int> sales; public: SalesPerson(string ID, string name, string sex, CDate date, string job, double basicmoney, map<int, int>sales) :Employee(ID, name, sex, date, job, basicmoney) { this->sales = sales; } double getpay(int m); }; #endif
//Employee.cpp: #include "Employee.h" #include <iostream> #include <algorithm> using namespace std; Employee::Employee(string ID, string name, string sex, CDate date, string job, double basicmoney) { this->ID = ID; this->name = name; this->sex = sex; this->date = date; this->basicmoney = basicmoney; this->job = job; } double Manager::getpay(int m) { return price[m] + basicmoney; } double Technicist::getpay(int m) { return basicmoney; } double SalesPerson::getpay(int m) { return basicmoney + sales[m] * 0.05; }
//Report.h: #include "Employee.h" class Report { private: list <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* p); void print(int n); };
//Report.cpp: #include "Employee.h" #include "Report.h" #include <algorithm> list <Employee*> Report::operator[](string job) { list<Employee*> cp; list<Employee*>::iterator it; for (it = members.begin(); it != members.end(); it++) { if ((*it)->getjob() == job) cp.push_back(*it); } return cp; } void Report::print(int month) { cout << " 第" << month << "月职工收入报表" << endl; cout << "---------------------------------------------------" << endl; cout << "职位:技术" << endl; cout << "工号\t" << "姓名\t" << "性别\t" << "入职时间\t" << "收入" << endl; list<Employee*> emp_ls; emp_ls = (*this)["技术"]; print(emp_ls, month); cout << "最低薪酬:" << min_pay(emp_ls, month) << endl; cout << "最高薪酬:" << max_pay(emp_ls, month) << endl; cout << "--------------------------------------------------" << endl; cout << "职位:经理" << endl; cout << "工号\t" << "姓名\t" << "性别\t" << "入职时间\t" << "收入" << endl; emp_ls = (*this)["经理"]; print(emp_ls, month); cout << "最低薪酬:" << min_pay(emp_ls, month) << endl; cout << "最高薪酬:" << max_pay(emp_ls, month) << endl; cout << "--------------------------------------------------" << endl; cout << "职位:销售" << endl; cout << "工号\t" << "姓名\t" << "性别\t" << "入职时间\t" << "收入" << endl; emp_ls = (*this)["销售"]; print(emp_ls, month); cout << "最低薪酬:" << min_pay(emp_ls, month) << endl; cout << "最高薪酬:" << max_pay(emp_ls, month) << endl; cout << "--------------------------------------------------" << endl; } double Report::min_pay(list<Employee*> emp_list, int month) { vector<double> pay; list<Employee*>::iterator it; for (it = emp_list.begin(); it != emp_list.end(); it++) { pay.push_back((*it)->getpay(month)); } return *min_element(pay.begin(), pay.end()); } double Report::max_pay(list<Employee*> emp_list, int month) { vector<double> pay; list<Employee*>::iterator it; for (it = emp_list.begin(); it != emp_list.end(); it++) { pay.push_back((*it)->getpay(month)); } return *max_element(pay.begin(), pay.end()); } void Report::print(list<Employee*> emp_list, int month) { list<Employee*>::iterator it; for (it = emp_list.begin(); it != emp_list.end(); it++) { cout << (*it)->getID() << "\t" << (*it)->getname() << "\t"; cout << (*it)->getsex() << "\t"; cout << (*it)->getdate().format("ddd") << "\t"; cout << (*it)->getpay(month) << endl; } } void Report::insert(Employee* p) { members.push_back(p); } Report::~Report() { list<Employee*>::iterator it; for (it = members.begin(); it != members.end(); it++) { delete* it; } }
//Main.cpp: #include <iostream> #include "Employee.h" #include<map> #include "Report.h" int main() { while (1) { cout << "请输入生成报表的月份" << endl << "退出请输入0" << endl; int month; cin >> month; if (month <= 0 || month > 12)exit(0); Report report; report.insert(new Technicist("0003", "朱黎明", "女", CDate(11, 8, 2001), "技术", 14000)); report.insert(new Technicist("0004", "刘改云", "女", CDate(8, 7, 2003), "技术", 11500)); report.insert(new Technicist("0008", "田静", "女", CDate(6, 7, 2014), "技术", 6000)); report.insert(new Technicist("00010", "许州", "男", CDate(27, 7, 2012), "技术", 8200)); map<int, int> b; b[1] = 1000; b[2] = 2000; b[3] = 1000; b[4] = 1000; b[5] = 2000; b[6] = 1000; b[7] = 1000; b[8] = 2000; b[9] = 1000; b[10] = 1000; b[11] = 2000; b[12] = 1000; report.insert(new Manager("0001", "王华", "女", CDate(2, 4, 2011), "经理", 7000, b)); b[1] = 500; b[2] = 1000; b[3] = 1000; b[4] = 1000; b[5] = 2000; b[6] = 1000; b[7] = 5000; b[8] = 2000; b[9] = 2000; b[10] = 1000; b[11] = 1000; b[12] = 1000; report.insert(new Manager("0002", "李明", "男", CDate(4, 10, 2009), "经理", 9000, b)); b[1] = 1000; b[2] = 0; b[3] = 3000; b[4] = 1000; b[5] = 2000; b[6] = 1000; b[7] = 1000; b[8] = 2000; b[9] = 1000; b[10] = 1000; b[11] = 5000; b[12] = 1000; report.insert(new Manager("0006", "刘向阳", "男", CDate(1, 11, 2010), "经理", 5000, b)); b[1] = 2000; b[2] = 2000; b[3] = 1000; b[4] = 1000; b[5] = 500; b[6] = 1000; b[7] = 2000; b[8] = 1000; b[9] = 5000; b[10] = 1000; b[11] = 500; b[12] = 1000; report.insert(new Manager("0009", "王浩", "女", CDate(10, 2, 2008), "经理", 10000, b)); map<int, int> sales; sales[1] = 200000; sales[2] = 100000; sales[3] = 500000; sales[4] = 200000; sales[5] = 100000; sales[6] = 500000; sales[7] = 200000; sales[8] = 100000; sales[9] = 500000; sales[10] = 200000; sales[11] = 100000; sales[12] = 500000; report.insert(new SalesPerson("0005", "李志武", "女", CDate(10, 11, 2007), "销售", 5000, sales)); sales[1] = 100000; sales[2] = 100000; sales[3] = 400000; sales[4] = 200000; sales[5] = 200000; sales[6] = 100000; sales[7] = 200000; sales[8] = 100000; sales[9] = 200000; sales[10] = 200000; sales[11] = 400000; sales[12] = 500000; report.insert(new SalesPerson("0007", "徐立春", "男", CDate(3, 9, 2010), "销售", 5000, sales)); sales[1] = 200000; sales[2] = 0; sales[3] = 500000; sales[4] = 200000; sales[5] = 100000; sales[6] = 500000; sales[7] = 100000; sales[8] = 400000; sales[9] = 400000; sales[10] = 200000; sales[11] = 500000; sales[12] = 200000; report.insert(new SalesPerson("00011", "方雪婷", "女", CDate(3, 9, 2015), "销售", 3000, sales)); report.print(month); } return 0; }
六 、运行结果
将想要得到工资报表的月份输入,输入1会得到1月份的员工收入报表,然后输入2,也将会得到2月份的员工收入报表,只有输入0才会退出程序。
编辑
编辑
七 、实验总结
本次实验知识涉及范围广,通过编写程序做实验的学习,我了解了STL容器的运用,也充分学到了继承和重载的知识,重载运算符,与成员函数、友员函数重载运算符的使用,以及虚函数和纯虚函数的使用方法,编写程序虽然困难,但最终也是逐一解决。所以本次实验学习到了很多知识,收益很多。