要求:
(1)由“房间”基类派生“教室”、“办公室”、“实验室”三个派生类,要求如下:
“教室”类包含:楼号、房间号、座位数、责任人(由1名行政人员担任);
“办公室”类包含:楼号、房间号、人员数量、行政人员1、行政人员2、…;
“实验室”类包含:楼号、房间号、教师数量、学生数量、教师1、教师2、…、学生1、学生2、…;
(2)其中“学生”、“教师”、“行政”三个派生类由“人员”基类派生,要求如下:
“学生”类包含:姓名、性别、学院、年龄、入学年份、专业;
“教师”类包含:姓名、性别、学院、年龄、职称、研究方向;
“行政”类包含:姓名、性别、学院、年龄、负责工作;
实验要求:
(1)请根据以上需求描述定义相应的基类与派生类,根据需求定义构造、析构、显示信息等成员函数;
(2)编写主程序验证功能,定义以下对象并在控制台输出相关信息:
教室1间;
办公室1间(包含至少2名行政);
实验室1间(包含至少2名教室、3名学生);
(3)注意:输出信息时要求通过运行时的多态实现;
一些相关问题:
1.“房间”基类中包含哪些数据成员?“人员”基类中包含哪些数据成员?
“房间”基类包含楼号和房间号;“人员”基类包含姓名、性别、学院、年龄;
2.结合需求,分析类与类之间的继承、聚合关系(哪些需要用到继承、多重继承?哪些需要使用聚合?);
①“房间”类和“人员”类都是基类,学生,教师,行政人员类均继承于“人员类”;
②而“教室”类需要一名行政人员,同时需要继承于“房间”类和“行政人员”类,这是多重继承;
③而“办公室”类,需要至少俩名行政人员,“实验室”类需要至少俩名教师和三名学生,他们都继承于“房间”类,但是需要一名以上的行政人员,教师,学生,不能区分,因此需要用到聚合;
3.简述赋值兼容原则;
赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员,而且所有成员的访问控制属性也和基类完全相同。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
即以“房间”基类为例,“教室”、“办公室”、“实验室”三个派生类继承了“房间”基类的楼号和房间号,即既可以实现房间的功能也可以实现它自身特有的功能,而反过来“房间”基类不能实现派生类的功能;
4.结合代码,简述如何实现运行时的多态性。
运行时多态性:C++运行时多态性主要是通过虚函数来实现的。体现在具有继承关系的父类和子类之间,子类重新定义父类的成员函数成为覆盖或者重写,而虚函数允许子类重新定义父类的成员函数,即重写父类的成员函数。
C++代码:
#include<iostream>
#include<string>
using namespace std;
enum Tsex {
mid, man, woman };
class Person {
private:
string Name; //姓名
Tsex Sex; //性别
string Academy; //学院
int Age; //年龄
public:
Person(string name, Tsex sex, string academy, int age)
{
Name = name;
Sex = sex;
Academy = academy;
Age = age;
}
Person() {
};
~Person() {
};
virtual void printInfo() {
//定义为虚函数,方便实现运行多态
cout << "姓名:" << Name << endl;
cout << "性别:";
switch (Sex) {
case 0:
cout << "mid" << endl; break;
case 1:
cout << "男" << endl; break;
case 2:
cout << "女" << endl;
}
cout << "学院:" << Academy << endl;
cout << "年龄:" << Age << endl;
}
};
class Student :public Person {
private:
int EntryYear; //入学年份
string Major; //专业
public:
Student(string, Tsex, string, int, int, string);
Student() {
};
~Student() {
};
void printInfo() //虚函数,打印学生情况
{
Person::printInfo();
cout << "入学年份:" << EntryYear << endl;
cout << "专业:" << Major << endl;
}
};
Student::Student(string name, Tsex sex, string academy, int age, int entryyear, string major) :Person(name, sex, academy, age) {
EntryYear = entryyear;
Major = major;
}
class Teacher :public Person {
private:
string AcademicTitle; //职称
string ResearchDir; //研究方向
public:
Teacher(string, Tsex, string, int, string, string);
Teacher() {
};
~Teacher() {
};
void printInfo() {
Person::printInfo();
cout << "职称:" << AcademicTitle << endl;
cout << "研究方向:" << ResearchDir << endl;
}
};
Teacher::Teacher(string name, Tsex sex, string academy, int age, string academictitle, string researchdir) :Person(name, sex, academy, age) {
AcademicTitle = academictitle;
ResearchDir = researchdir;
}
class Administration :public Person {
private:
string ResWork; //负责工作
public:
Administration(string, Tsex, string, int, string);
Administration() {
};
~Administration() {
};
void printInfo() {
Person::printInfo();
cout << "负责工作:" << ResWork << endl;
}
};
Administration::Administration(string name, Tsex sex, string academy, int age, string reswork) :Person(name, sex, academy, age) {
ResWork = reswork;
}
class ROOM {
private:
string BuildingName; //建筑名
int RoomNum; //房间号
public:
ROOM() {
};
ROOM(string buildname, int roomnum) {
//定义基类的构造函数
BuildingName = buildname;
RoomNum = roomnum;
}
~ROOM() {
};
virtual void printInfo() {
cout << "楼号:" << BuildingName << endl;
cout << "房间号:" << RoomNum << endl;
}
};
class ClassRoom :public ROOM, public Administration {
//教室有一名行政人员
private:
int SeatNum; //座位数
public:
ClassRoom() {
};
ClassRoom(string, int, int, string, Tsex, string, int, string);
~ClassRoom() {
};
void printInfo() {
cout << "该教室信息:" << endl;
ROOM::printInfo();
cout << "座位数:" << SeatNum << endl;
cout << "配备人员信息:" << endl;
Administration::printInfo();
}
};
ClassRoom::ClassRoom(string buildname, int roomnum, int seatnum, string name, Tsex sex, string academy, int age, string reswork) :ROOM(buildname, roomnum), Administration(name, sex, academy, age, reswork) {
SeatNum = seatnum;
}
class Office :public ROOM {
//办公室至少2名行政人员
private:
int PersonNum; //人员数
int RePersonNum = 0; //实际配备的人员数量
Administration** ad; //构造函数里面分配内存
public:
Office() {
};
Office(string, int, int);
~Office() {
delete[] ad;
}
void printInfo() {
cout << "该办公室信息:" << endl;
ROOM::printInfo();
cout << "最大配置行政人员人数量:" << PersonNum << endl;
cout << "实际人员数量:" << RePersonNum << endl;
cout << "行政人员个人信息如下:" << endl;
for (int i = 0; i < RePersonNum; i++) {
cout << i + 1 << ":" << endl;
ad[i]->printInfo();
cout << endl;
}
}
void AddAdministration(string, Tsex, string, int, string); //添加新人员
};
Office::Office(string buildname, int roomnum, int personnum) :ROOM(buildname, roomnum) {
PersonNum = personnum;
ad = new Administration *[PersonNum]; //内存动态分配
}
void Office::AddAdministration(string name, Tsex sex, string academy, int age, string reswork) {
if (RePersonNum >= PersonNum) {
cout << "办公室已满人:" << endl;
}
else {
ad[RePersonNum++] = new Administration(name, sex, academy, age, reswork);
}
}
class Lab : public ROOM{
private:
int TeacherNum;
int StudentNum;
int ReTeacherNum ;
int ReStudentNum ;
Teacher** t;
Student** s;
public:
Lab() {
};
Lab(string, int, int, int);
~Lab();
void AddTeach(string, Tsex, string, int, string, string);
void AddStu(string, Tsex, string, int, int, string);
void printInfo() {
cout << "实验室信息如下:" << endl;
ROOM::printInfo();
cout << "最大容纳教师人数:" << TeacherNum << endl;
cout << "实际教师人数:" << ReTeacherNum << endl;
cout << "教师信息如下:" << endl;
for (int i = 0; i < ReTeacherNum; i++) {
cout << i + 1 << ":" << endl;
t[i]->printInfo();
cout << endl;
}
cout << "最大容纳学生人数:" << StudentNum << endl;
cout << "实际学生人数:" << ReStudentNum << endl;
cout << "教师信息如下:" << endl;
for (int i = 0; i < ReStudentNum; i++) {
cout << i + 1 << ":";
s[i]->printInfo();
cout << endl;
}
}
};
Lab::Lab(string buildname, int roomnum, int teachernum, int studentnum) :ROOM(buildname, roomnum) {
TeacherNum = teachernum;
StudentNum = studentnum;
t = new Teacher *[TeacherNum];
s = new Student *[StudentNum];
}
void Lab::AddTeach(string name, Tsex sex, string academy, int age, string academictitle, string researchdir) {
if (ReTeacherNum >= TeacherNum) {
cout << "该实验室老师已满人,无法添加" << endl;
}
else {
t[ReTeacherNum++] = new Teacher(name, sex, academy, age, academictitle, researchdir);
}
}
void Lab::AddStu(string name, Tsex sex, string academy, int age, int entryyear, string major) {
if (ReStudentNum >= StudentNum) {
cout << "该实验室学生已满人,无法添加" << endl;
}
else {
s[ReStudentNum++] = new Student(name, sex, academy, age, entryyear, major);
}
}
Lab::~Lab() {
delete[] t;
delete[] s;
}
//引用方式的多态运行
void Claroom(ROOM& r) {
r.printInfo();
}
int main()
{
Person per("小明", man, "电信", 20);
Student stu("小红", woman, "电信", 20, 2020, "电子与信息工程");
Teacher tea("小绿", mid, "电信", 25, "博导", "单片机");
Administration adm0("小明0", man, "电信", 25, "老师");
Administration adm1("小明1", man, "电信", 25, "管理");
Administration adm2("小明2", man, "电信", 25, "检查");
ROOM* r; //基类指针
ClassRoom cla("L", 411, 50, "小明0", man, "电信", 25, "管理");
Claroom(cla);
//r = &cla; //指向派生类对象
//r->printInfo(); //调用派生类成员函数
Office off("L", 411, 5);
off.AddAdministration("小明0", man, "电信", 20, "教学");
off.AddAdministration("小明1", man, "电信", 20, "管理");
off.AddAdministration("小明2", man, "电信", 20, "检查");
Claroom(off);
//r = &off; //指向派生类对象
//r->printInfo(); //调用派生类成员函数
Lab N411("致信楼", 411, 3, 3);
N411.AddTeach("小红", man, "电子与信息工程", 25, "副教授", "天线雷达");
N411.AddTeach("小橙", man, "电子与信息工程", 25, "副教授", "天线雷达");
N411.AddTeach("小黄", man, "电子与信息工程", 25, "副教授", "天线雷达");
N411.AddStu("小绿", man, "电子与信息工程", 20, 2020, "电子信息工程");
N411.AddStu("小蓝", man, "电子与信息工程", 20, 2020, "电子信息工程");
N411.AddStu("小靛", man, "电子与信息工程", 20, 2020, "电子信息工程");
//N411.AddStu("小紫", man, "电子与信息工程", 20, 2020, "电子信息工程");
Claroom(N411); //运行多态由引用方式实现
//r = &N411; //运行多态由指针方式实现
//r->printInfo();//运行多态由指针方式实现
return 0;
}
运行结果: