JiLin University 面向对象程序设计第三题实验报告

本文介绍了一个使用C++实现的雇员工资发放系统,涵盖了周薪、时薪、佣金和带底薪佣金四种雇员类型。系统中包含抽象类Employee、日期类Date以及各个雇员子类,实现了工资计算、信息显示、生日奖励和特定雇员奖励等功能。通过多态调用,可以管理和输出不同类型的雇员工资。
摘要由CSDN通过智能技术生成
  • 实验题目

为某公司设计雇员工资发放系统。

每个雇员的基本信息包括:姓名(name),工号(id)。

雇员的收入取决于雇员的类型。该公司共有四类雇员:

周薪雇员(SalariedEmployee):收入=固定周薪。

时薪雇员(HourlyEmployee):若工作40小时以下,收入=小时数*每小时薪水;若工作40小时以上,收入=40*每小时薪水+(小时数-40)*每小时薪水*150%。

佣金雇员(CommissionEmployee):收入=销售量*每个商品的销售佣金

带底薪佣金雇员(BasePlusCommissionEmployee):收入=底薪+销售量*每个商品的销售佣金

要求:建立雇员继承层次,每个类包含计算工资和显示输出的功能,可以计算和显示输出公司雇员(Employee)的每周收入。输出时要显示该类雇员的所有信息。(包括雇员类型、姓名、工号、工资各项明细),写出主函数测试各类。在雇员基本信息中增加雇员的生日(birthDate),并设计日期类(Date)来表示生日。在主函数中创建一个容器用来管理公司各种雇员对象,多态地计算并输出每个雇员的工资。如果雇员的生日在本月,就奖给该雇员100元。同时,在本次工资发放阶段,公司决定奖励带薪佣金雇员,把他们的基本工资提高10%。

设计提示:使用抽象类。

  • 解决方案

1.设计日期类(Date):

包含年(year)、月(month)、日(day)三个成员变量。

提供日期比较(比如是否在本月)的方法。

2.设计雇员基类(Employee):

声明为抽象类。

包含姓名(name)、工号(id)、生日(birthDate)三个成员变量。

声明纯虚函数double calculateSalary()来计算工资。

声明虚函数void display()来显示雇员信息。

3.设计各类雇员类:

从Employee类继承。

实现各自的calculateSalary()函数来根据雇员类型计算工资。

实现display()函数来显示雇员的详细信息。

4.设计主函数:

创建一个包含不同雇员类型的容器(比如std::vector<std::unique_ptr<Employee>>)。

遍历容器,使用多态调用calculateSalary()和display()函数来计算和显示工资。

检查雇员生日是否在本月,并相应调整工资。

对于带底薪佣金雇员,增加10%的基本工资。

注:本程序分别添加了一位周薪雇员,一位时薪雇员,一位佣金雇员,一位带底薪佣金雇员,其中有两位生日在5月。

  • 程序清单

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>

#include <vector>

#include <ctime>

// 日期类

class Date {

public:

    int year, month, day;

    Date(int y = 0, int m = 0, int d = 0) : year(y), month(m), day(d) {}

    // 判断日期是否在当前月份

    bool isThisMonth(const time_t& now) const {

        struct tm* timeinfo = localtime(&now);

        return month == timeinfo->tm_mon + 1;

    }

};

// 雇员基类(抽象类)

class Employee {

public:

    std::string name;

    int id;

    Date birthDate;

    Employee(const std::string& n, int i, int y, int m, int d)

        : name(n), id(i), birthDate(y, m, d) {}

    virtual double calculateSalary() const = 0; // 纯虚函数

    virtual void display() const = 0; // 纯虚函数

    virtual ~Employee() {}

};

// 周薪雇员

class SalariedEmployee : public Employee {

    double weeklySalary;

public:

    SalariedEmployee(const std::string& n, int i, double s, int y, int m, int d)

        : Employee(n, i, y, m, d), weeklySalary(s) {}

    double calculateSalary() const override { return weeklySalary; }

    void display() const override {

        std::cout << "SalariedEmployee: " << name << ", ID: " << id

            << ", Salary: $" << calculateSalary() << std::endl;

    }

};

// 时薪雇员

class HourlyEmployee :public Employee {

    double everyhourSalary;

    double hours;

public:

    HourlyEmployee(const std::string& n, int i, double e,double h ,int y, int m, int d)

        : Employee(n, i, y, m, d), everyhourSalary(e),hours(h) {}

    double calculateSalary() const override {

        if (hours <= 40)

            return hours * everyhourSalary;

        else

            return 40 * everyhourSalary + (hours - 40) * everyhourSalary * 1.5;

    }

    void display() const override {

        std::cout << "HourlyEmployee: " << name << ", ID: " << id

            << ", Salary: $" << calculateSalary() << std::endl;

    }

};

// 佣金雇员

class CommissionEmployee :public Employee {

    int salesvolume;

    double everycommission;

public:

    CommissionEmployee(const std::string& n, int i, int s, double e, int y, int m, int d)

        : Employee(n, i, y, m, d), salesvolume(s), everycommission(e){}

    double calculateSalary() const override {

        return salesvolume * everycommission;

    }

    void display() const override {

        std::cout << "CommissionEmployee: " << name << ", ID: " << id

            << ", Salary: $" << calculateSalary() << std::endl;

    }

};

// 带底薪佣金雇员

class BasePlusCommissionEmployee : public Employee {

    double baseSalary;

    double commissionRate;

    double sales;

public:

    BasePlusCommissionEmployee(const std::string& n, int i, double b, double c, double s, int y, int m, int d)

        : Employee(n, i, y, m, d), baseSalary(b), commissionRate(c), sales(s) {}

    double calculateSalary() const override {

        return baseSalary *1.1 + sales * commissionRate;  

    }

    void display() const override {

        std::cout << "BasePlusCommissionEmployee: " << name << ", ID: " << id

            << ", Salary: $" << calculateSalary()

            << ", Base Salary: $" << baseSalary *1.1

            << ", Commission: $" << sales * commissionRate

            << std::endl;

    }

};

// 主函数

int main() {

    std::vector<Employee*> employees;

    // 假设今天是5月20日

    time_t now = time(nullptr);

    struct tm* localTime = localtime(&now);

    int currentYear = localTime->tm_year + 1900;

    int currentMonth = localTime->tm_mon + 1;

    //添加一个周薪雇员

    SalariedEmployee* employee_S = new SalariedEmployee("马", 7, 5000.0, 2005, 9, 30);

    if (employee_S->birthDate.isThisMonth(now)) {

        // 假设这里只是简单打印出奖励信息,实际中可能需要更新雇员的工资或其他属性

        std::cout << employee_S->name << " birthday bonus: $100" << std::endl;

    }

    employees.push_back(employee_S);

    //添加一个时薪雇员

    HourlyEmployee* employee_H = new HourlyEmployee("陶", 6, 100, 6, 2004, 5, 2);

    if (employee_H->birthDate.isThisMonth(now)) {

        std::cout << employee_H->name << " birthday bonus: $100" << std::endl;

    }

    employees.push_back(employee_H);

    //添加一个佣金雇员

    CommissionEmployee* employee_C = new CommissionEmployee("姜", 5, 120, 23.4, 2006, 11, 12);

    if (employee_C->birthDate.isThisMonth(now)) {

        std::cout << employee_C->name << " birthday bonus: $100" << std::endl;

    }

    employees.push_back(employee_C);

    //添加一个带底薪佣金雇员

    BasePlusCommissionEmployee* employee_B = new BasePlusCommissionEmployee("万", 1, 500.0, 0.1, 1000.0, 1980, 5, 20);

    if (employee_B->birthDate.isThisMonth(now)) {

        std::cout << employee_B->name << " birthday bonus: $100" << std::endl;

    }

    employees.push_back(employee_B);

    // 遍历并计算和显示每个雇员的工资

    for (Employee* emp : employees) {

        emp->display();

    }

    return 0;

}

  • 体会与总结

(一)知识点理解

1.抽象类(Abstract Class):

抽象类不能被实例化,通常用于定义一个接口,该接口由派生类实现。

抽象类可以包含纯虚函数(只有声明,没有定义的函数),派生类必须实现这些纯虚函数。

2.继承(Inheritance):

继承允许我们定义一个派生类(子类),它继承了一个或多个基类(父类)的特性(数据成员和成员函数)。

通过继承,子类可以重用父类的代码,并实现自己的特定功能。

3.多态(Polymorphism):

多态允许我们使用父类类型的指针或引用来调用子类对象的方法。

在运行时,根据指针或引用所指向的实际对象类型来确定调用哪个方法。

(二)运行情况分析

在实现雇员工资发放系统时,我们首先需要定义Employee基类,它是一个抽象类,包含了所有雇员的公共属性(如姓名、工号、生日)和纯虚函数(如calculateSalary和display)。然后,我们为每种类型的雇员定义了一个派生类,实现了自己的calculateSalary和display函数。

在主函数中,我们创建了一个std::vector<std::unique_ptr<Employee>>容器来存储不同类型的雇员对象。由于使用了智能指针,我们不需要担心内存泄漏问题。然后,我们遍历容器,使用多态来调用每个雇员的calculateSalary和display函数,计算和显示每个雇员的工资。

对于生日奖励和底薪佣金雇员的奖励,我们可以在调用calculateSalary函数时进行检查和处理。

(三)调试程序获得的经验与体会

在调试程序时,我遇到了几个常见的问题:

1.内存泄漏:由于C++中手动管理内存,很容易忘记释放分配的内存,导致内存泄漏。通过使用智能指针(如std::unique_ptr),我们可以避免这个问题。

2.类型错误:在使用多态时,如果父类和子类的函数签名不一致,或者子类没有实现父类的纯虚函数,编译器会报错。因此,我们需要仔细检查类层次结构中的函数签名。

3.逻辑错误:在计算工资和显示信息时,可能会出现逻辑错误。例如,忘记考虑生日奖励或底薪佣金雇员的奖励。通过编写详细的测试用例并仔细测试每个功能,我们可以发现和修复这些错误。

4.可读性:为了提高代码的可读性,我们应该遵循良好的编程规范,如使用有意义的变量名、添加注释、保持代码结构清晰等。这有助于我们和其他开发人员更好地理解代码。

  • 28
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值