C++实验三:类的多态性的实现——工资报表

简介: 某公司的员工有经理Manager、技术人员Technicist和营销人员SalsePerson,他们的薪金计算方法如下: 经理按月计酬,方法是:基本工资+奖金;技术人员按月计酬,方法是:基本工资;营销人员按月计酬,方法是:基本工资+销售利润*5%。其中基本工资为8000元再加上工龄工资。工龄工资就是雇员在该公司工作的工龄每增加一年,月工资就增加200元。 每类人员都有职工编号、姓名、性别、入职时间、职位、基本工资等数据;各类人员使用统一接口get_pay()计算各类人员的月薪,重载<<运算符实现

一、实验目的

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);
};

image.gif

//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;
}

image.gif

//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

image.gif

//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;
}

image.gif

//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);
};

image.gif

//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;
    }
}

image.gif

//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;
}

image.gif

六 、运行结果

将想要得到工资报表的月份输入,输入1会得到1月份的员工收入报表,然后输入2,也将会得到2月份的员工收入报表,只有输入0才会退出程序。

image.gif编辑

image.gif编辑

七 、实验总结

本次实验知识涉及范围广,通过编写程序做实验的学习,我了解了STL容器的运用,也充分学到了继承和重载的知识,重载运算符,与成员函数、友员函数重载运算符的使用,以及虚函数和纯虚函数的使用方法,编写程序虽然困难,但最终也是逐一解决。所以本次实验学习到了很多知识,收益很多。

相关文章
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
60 2
|
2月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
111 5
|
2月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
111 4
|
2月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
146 4
|
3月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
35 4
|
3月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
33 4
|
3月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
30 1
|
3月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
3月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
3月前
|
存储 编译器 C语言
【C++类和对象(上)】—— 我与C++的不解之缘(三)
【C++类和对象(上)】—— 我与C++的不解之缘(三)