定义一个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循环,感兴趣可以自行了解