6-7 定义一个Staff_List类

定义一个Staff_list类,根据main的需求设计数据成员和成员函数,完成输入员工(人数不超过100)信息的存储和输出。
class Date;
class Staff;
class Teacher;
class Ad_Staff:;
class Tea_Ad_Staff;
class O_Teacher;
以上类代码用前面1~6题自己定义的类。

思考

思考Staff_list存储员工数据时应该采用什么数据结构合适?

语法知识点

1.基类和公有派生类赋值兼容规则
2.虚函数

函数接口定义:

int main()

裁判测试程序样例:

/* 请在这里填写答案 */
int main()
{
    int n;
    //     姓名 部门 职称   职位      单位
    string name,dept,title,postation,company;
    //sex性别
    char sex,c;
    int byear,bmonth,bday,eyear,emonth,eday;    
    double salary;
    Staff_list L;
    while(cin>>n && n!=0)
    {
        cin>>name>>sex;        
        cin>>byear>>c>>bmonth>>c>>bday;
        cin>>eyear>>c>>emonth>>c>>eday;
        cin>>dept>>salary;
        // e_date入职日期 b_date 出生日期
        Date e_date(eyear,emonth,eday),b_date(byear,bmonth,bday);
        switch(n)
        {
            //添加教师 
            case 1:{                            
                cin>>title;
                Teacher t(name,sex,b_date,e_date,dept,salary,title);
                L.Add(t);                
                break;
            }
            //添加行政人员 
            case 2:{
                cin>>postation;
                Ad_Staff as(name,sex,b_date,e_date,dept,salary,postation);
                L.Add(as);                
                break;
            }
            //添加双挑人员 
            case 3:{
                cin>>postation;
                cin>>title;
                Tea_Ad_Staff tas(name,sex,b_date,e_date,dept,salary,postation,title);
                L.Add(tas);                
                break;
            }
            //添加外聘教师 
            case 4:{
                cin>>title;
                cin>>company;
                O_Teacher ot(name,sex,b_date,e_date,dept,salary,title,company);
                L.Add(ot);    
                break;
            }
        }        
    }
    L.printAll();
    return 0;
}

输入样例:

2
李晓敏 f 1986-6-7 2011-7-1 应用数学 5500 教务员
1
黄柏松 m 1980-3-27 2008-7-1 计算机  7500 教授
3
王大明 m 1988-4-25 2018-7-1 管理学院 8500 教授 院长
4
张小兰 f 1985-6-26 2021-7-1 计算机 5000 副教授  兰州大学
1
李达国 m 1988-4-25 2018-7-1 政法学院 8500 教授
0

输出样例:

所有员工信息如下:
No 1 行政人员
姓名:李晓敏
性别:女
出生日期:1986年06月07日
入职日期:2011年07月01日
部门:应用数学
工资:5500
职位:教务员

No 2 专任教师
姓名:黄柏松
性别:男
出生日期:1980年03月27日
入职日期:2008年07月01日
部门:计算机
工资:7500
职称:教授

No 3 双挑人员
姓名:王大明
性别:男
出生日期:1988年04月25日
入职日期:2018年07月01日
部门:管理学院
工资:8500
职称:教授
职位:院长

No 4 外聘教师
姓名:张小兰
性别:女
出生日期:1985年06月26日
入职日期:2021年07月01日
部门:计算机
工资:5000
职称:副教授
单位:兰州大学

No 5 专任教师
姓名:李达国
性别:男
出生日期:1988年04月25日
入职日期:2018年07月01日
部门:政法学院
工资:8500
职称:教授


代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

前言

第一次写的话,这道题还是颇为折磨的,不太适合放在继承专题,更适合放在多态.

只需要搞懂思考语法知识点就能搞懂大半,剩下的一小部分在于如何获取当前类是什么类型,解法或许多样,这小部分我参考了AI给出的回答,辅以我的见接,希望对你有帮助.

代码实现

#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;


//Date为Staff的对象成员
class Date 
{
protected:
    int year, month, day;
public:
    Date(int year, int month, int day) : year(year), month(month), day(day)
    {
        
    }
     void show()
    {
         cout << setfill('0') << setw(4) << year
             << "年" << setw(2) << month << "月" << setw(2) 
             << day << "日" << endl;
    }
};

//基类,声明虚函数
class Staff
{
protected:
    Date b_date, e_date;
    string name, dept;
    char sex;
    double salary;
public:
    Staff(string name, char sex, Date b, Date e, string dept, double salary)
        :name(name), sex(sex), b_date(b), e_date(e), dept(dept), salary(salary)
        {
            
        }

    virtual void show ()    //虚函数
    {
        cout << "姓名:" << name << endl
            << "性别:";
         if (sex == 'f') cout << "女";
             else cout << "男";
        cout << endl << "出生日期:";
        b_date.show();
        cout << "入职日期:";
        e_date.show();
        cout << "部门:" << dept << endl
            << "工资:" << salary << endl;
    }

    virtual Staff* clone() const //补充clone函数,实现对象深拷贝
    {
        return new Staff(*this);
    }

    virtual ~Staff() {}    //必须补充虚析构函数
};

//中间类
class Teacher : virtual public Staff
{
protected:
    string title;
public:
    Teacher(string name, char sex, Date b, Date e, string dept, double salary, string title)
    : Staff(name, sex, b, e, dept, salary), title(title) {}

    void show () override
    {
        cout << "专任教师" << endl;
        Staff::show();
        cout << "职称:" << title << endl;
    }

    Teacher* clone() const override
    {
        return new Teacher(*this);
    }
};


//中间类
class Ad_Staff : virtual public Staff
{
protected:
    string postation;
public:
    Ad_Staff(string name, char sex, Date b, Date e, string dept, double salary, string p)
    :Staff(name, sex, b, e, dept, salary), postation(p) {}

    void show () override
    {
        cout << "行政人员" << endl;
        Staff::show();
        cout << "职位:" << postation << endl;
    }

    Ad_Staff* clone() const override
    {
        return new Ad_Staff(*this);
    }
};


//菱形继承下来的类
class Tea_Ad_Staff : public Teacher, public Ad_Staff
{
public:
    Tea_Ad_Staff(string name, char sex, Date b, Date e, string dept, double salary, string t, string p)
     : Staff(name, sex, b, e, dept, salary), Teacher(name, sex, b, e, dept, salary,t),
       Ad_Staff(name, sex, b, e, dept, salary, p) {}

      void show () override
      {
          cout << "双挑人员" << endl;
          Staff::show();
          cout << "职称:" << title << endl;
          cout << "职位:" << postation << endl;
      }

      Tea_Ad_Staff* clone() const override
      {
          return new Tea_Ad_Staff(*this);
      }
};

//另一条分支继承下来的类
class O_Teacher : public Teacher
{
protected:
    string company;
public:
    O_Teacher(string name, char sex, Date b, Date e, string dept, double salary, string title, string c)
    : Staff(name, sex, b, e, dept, salary), Teacher(name, sex, b, e, dept, salary, title), company(c) {}

    void show () override
    {
        cout << "外聘教师" << endl;
        Staff::show();
        cout << "职称:" << title << endl;
        cout << "单位:" << company << endl;
    }

    O_Teacher* clone() const override
    {
        return new O_Teacher(*this);
    }

};






class Staff_list
{
protected:
     int num; //不需要static,因为只有一个对象
     vector<Staff*> s;    //用动态指针数组存储
public:
    Staff_list() { num = 0; }

    // 解题重点在于动态多态,兼容所有派生类
    // 形参用父类的引用对象,可以兼容子类的对象
    void Add(Staff &st)    //用父类的(多态)
    {
        num++;
        s.push_back(st.clone());
    }


    void printAll()    //对齐输出样例
    {
         cout << "所有员工信息如下:" << endl;
        for (int i = 0; i < num; i++)
        {
            cout << "No " << i+1 << " ";
            s[i]->show();
            cout << endl;
        }
    }

        ~Staff_list() {
        for (auto ptr : s) {
            delete ptr;
        }
    }

};



/* 解题重点
1.利用统一接口接收派生类,需要理解动态多态以及基类和派生类的赋值兼容规则
2.正确写出基类虚函数和重写的show函数(建议override显式声明)
3.存储员工数据时应采用【基类的指针】这种元素类型
4.需要在每个类中多写一个clone函数(推荐加const),返回由动态开辟(new)的本体(*this)的指针
  通过这个函数实现[基类指针]类型变量正确接收派生类的元素类型
5.必须利用clone实现深拷贝,浅拷贝会导致内存超限(不知道是不是这个原因,我遇到的就是这样)
6.因为会通过基类指针接收派生类对象,虚析构函数需要补充


*/

本题的难点就在于如何接收派生类的对象,学习多态会使得写这道题更加得心应手,不适合只学了继承知识点写这道题.

其中,vector(向量)是一种容器,在学习STL时会介绍,只需要理解为它是个动态数组即可,本题用

Staff* s[100];

即可解决.

末尾释放使用的增强型for循环等同于普通for循环,感兴趣可以自行了解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值