验:编写一个人员信息管理系统。这个系统的功能是:交互式的实现校园人员信息的录入与显示。
分析:
学校里,主要有四类人员:大学本科学生、教师、研究生和助教。
大学本科生每周有固定的学时数。教师除了固定的学时数外,还有每周的教学时数。研究生除了固定的学时数外,每周还可以自由做一定的研究。助教生除了上课外,还要做研究和一定的教学工作。
人员的基本信息包括姓名、编号、性别、身份证号、总学时数以及每周固定学时数。各个人员之间的关系: people类派生出student 类和teacher类,student 类派生出graduate类, graduate类和teacher类派生出TA类。
这道题难度其实并不大,它就像高考的统概题似的,主要考察大家的细心耐心。和高考不同,你写代码出bug了没关系,反正可以修的嘛~(以下冥场面)
好了,吹水环节结束,接下来进入正题。
审题之后我们可以知道这些类之间的关系 如图:
知道了这些关系,有利于我们理清他们各自的数据成员之间看似错综复杂的关系
简单来说,基类拥有的数据成员在派生类中也可使用,而派生类中可以定义一些基类所没有的数据成员。再结合题意,分清每种类分别具有哪些基本信息,我们就能写出类的雏形。
注意:由于TA的两个基类student和graduate具有相同的基类people,在这种情况下,TA中从people继承到的数据成员会产生二义性,为避免这种情况的发生,我们需要将teache和student声明为people的虚派生类,从而让编译器在建立对象时由virtual统一指引建立TA类中数据成员的指针
写起来很简单,但这个细节十分重要!代码如下:
class people
{
protected:
string names;//姓名
bool sex;//性别
string ID;//身份证号
double Alltime;//总学时数
double Weektime;//周学时数
};
class student : virtual public people
{};
class teacher :virtual public people
{
protected:double Teachtime;//教学时数
};
class graduate : virtual public student
{
protected:double Studytime;//研究时数
};
class TA : public graduate, public teacher
{};
可能有同学就要问了,啊这个student类和TA类里面怎么什么都没有呢?此时继承这一功能的强大之处就体现出来了。在基类中已经定义过的数据成员,在派生类中可以直接使用,由于这两个类中的数据成员都与基类重复,故不用再定义。
回过头来再看一眼题,本题需要实现的核心功能是录入与显示,也就是用成员函数print和input实现输入与输出。由于本题中的函数之间具有继承关系,若直接对print和input进行重载,则会默认调用基类版本的函数,这显然不是我们想要的。所以需要用到虚函数来实现多态的调用。
class people
{
public:
void print() {
if (sex)
cout << "\n姓名:" << names << "\n性别:男\n身份证号:" << ID << "\n总学时数:" << Alltime << "\n周学时数:" << Weektime << endl;
else
cout << "\n姓名:" << names << "\n性别:女\n身份证号:" << ID << "\n总学时数:" << Alltime << "\n周学时数:" << Weektime << endl;
}
virtual void input() = 0;
};
class student : virtual public people
{
public:
friend void finding(student* p3, string nam);
friend void change(student* p3, string nam);
void print() { people::print(); }
void input()
{
cout << "请输入姓名:\n";
cin >> names;
cout << "请输入性别代码(1为男性,0为女性):\n";
cin >> sex;
cout << "请输入身份证号:\n";
cin >> ID;
cout << "请输入总学时数:\n";
cin >> Alltime;
cout << "请输入周学时数:\n";
cin >> Weektime;
}
private:
};
class teacher :virtual public people
{
public:
friend void finding( teacher* p2, string nam);
friend void change(teacher* p2, string nam);
void input()
{
cout << "请输入姓名:\n";
cin >> names;
cout << "请输入性别代码(1为男性,0为女性):\n";
cin >> sex;
cout << "请输入身份证号:\n";
cin >> ID;
cout << "请输入总学时数:\n";
cin >> Alltime;
cout << "请输入周学时数:\n";
cin >> Weektime;
cout << "请输入教学时数:\n";
cin >> Teachtime;
}
void print()
{
people::print();
cout << "教学时数:" << Teachtime<<endl;
}
};
class graduate : virtual public student
{
public:
friend void finding( graduate* p4, string nam);
friend void change(graduate* p4, string nam);
void print()
{
student::print();
cout << "研究时数:\n" << Studytime << endl;;
}
void input()
{
student::input();
cout << "请输入研究时数:\n";
cin >> Studytime;
}
protected:double Studytime;
};
class TA : public graduate, public teacher
{
public:
friend void finding(TA* p1, string nam);
friend void change(TA* p1, string nam);
void print()
{
teacher::print();
cout << "研究时数:" << Studytime << endl;
}
void input()
{
teacher::input();
cout << "请输入研究时数:\n";
cin >> Studytime;
}
private:
};
接下来的问题就是如何实现交互式的程序。在主函数中,我采用上个学期教的while(1){}的死循环方法,让程序不断地运行下去,直到人为打断或手动退出。首先定义四种身份类的数组和计数器
TA ta[100];
student st[100];
teacher tc[100];
graduate gr[100];
int nta = 0, nst = 0, ntc = 0, ngr = 0;//统计录了几个数据
其次调用前面写的成员函数input()进行数据录入,并统计录入的数据个数
int main()
{
while (1)
{
int x = 0;
cout << "\n功能菜单:1.录入 2.查询\n ";
cin>>x ;
int kin;
if (x == 1)
{
cout << "请选择你要录入的身份:1.学生2.教师3.研究生4.助教";
kin = choose();
if (kin == 1) { st[nst++].input(); }
if (kin == 2) { tc[ntc++].input(); }
if (kin == 3) { gr[ngr++].input(); }
if (kin == 4) { ta[nta++].input(); }
}
}
这边的程序可以实现录入和查找两个功能 。查找功能要如何实现呢?关于查找的算法有很多,和排序一样是编程过程中十分实用的算法。但毕竟这只是作业,不是算法题,对时间复杂度和空间复杂度没有太多的要求,所以这边展示最基础暴力的查找方法:直接遍历数组以进行查找
void finding(TA* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].print();
a = 1;
}
}
}
void finding(student* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam))
{
p1[i].print(); a = 1;
}
}
}
void finding(teacher* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].print(); a = 1;
}
}
}
void finding(graduate* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].print(); a = 1;
}
}
运用c++自带的string类处理函数compare对要查找的nam和数组中已录入的names进行比对,若相同则将其输出。细心的同学可能会发现这边还有一个a=1;这个a则是我设置的一个信号,若查找到,则置1,若未查到,则为初始值。这样就能实现在没有查找到结果的时候提示没有查到结果。
至此,这道题就写完了,完整代码供学习参考(注:本程序未设置出口,若需要结束程序,请直接右上角x;本程序仅设置按照提示输入时的情况,请按提示输入以防程序崩溃):
#include <iostream>
#include<cstring>
using namespace std;
/*人员的基本信息包括姓名、编号、性别、身份证号、总学时数以及每周固定学时数。*/
/*大学本科生每周有固定的学时数。教师除了固定的学时数外,还有每周的教学时数。
研究生除了固定的学时数外,每周还可以自由做一定的研究。助教生除了上课外,还要做研究和一定的教学工作。*/
class people
{
public:
void print() {
if (sex)
cout << "\n姓名:" << names << "\n性别:男\n身份证号:" << ID << "\n总学时数:" << Alltime << "\n周学时数:" << Weektime << endl;
else
cout << "\n姓名:" << names << "\n性别:女\n身份证号:" << ID << "\n总学时数:" << Alltime << "\n周学时数:" << Weektime << endl;
}
virtual void input() = 0;
protected:
string names;
bool sex;
string ID;
double Alltime;
double Weektime;
};
class student : virtual public people
{
public:
friend void finding(student* p3, string nam);
friend void change(student* p3, string nam);
void print() { people::print(); }
void input()
{
cout << "请输入姓名:\n";
cin >> names;
cout << "请输入性别代码(1为男性,0为女性):\n";
cin >> sex;
cout << "请输入身份证号:\n";
cin >> ID;
cout << "请输入总学时数:\n";
cin >> Alltime;
cout << "请输入周学时数:\n";
cin >> Weektime;
}
private:
};
class teacher :virtual public people
{
public:
friend void finding( teacher* p2, string nam);
friend void change(teacher* p2, string nam);
void input()
{
cout << "请输入姓名:\n";
cin >> names;
cout << "请输入性别代码(1为男性,0为女性):\n";
cin >> sex;
cout << "请输入身份证号:\n";
cin >> ID;
cout << "请输入总学时数:\n";
cin >> Alltime;
cout << "请输入周学时数:\n";
cin >> Weektime;
cout << "请输入教学时数:\n";
cin >> Teachtime;
}
void print()
{
people::print();
cout << "教学时数:" << Teachtime<<endl;
}
protected:double Teachtime;
};
class graduate : virtual public student
{
public:
friend void finding( graduate* p4, string nam);
friend void change(graduate* p4, string nam);
void print()
{
student::print();
cout << "研究时数:\n" << Studytime << endl;
}
void input()
{
student::input();
cout << "请输入研究时数:\n";
cin >> Studytime;
}
protected:double Studytime;
};
class TA : public graduate, public teacher
{
public:
friend void finding(TA* p1, string nam);
friend void change(TA* p1, string nam);
void print()
{
teacher::print();
cout << "研究时数:" << Studytime << endl;
}
void input()
{
teacher::input();
cout << "请输入研究时数:\n";
cin >> Studytime;
}
private:
};
int choose()
{
int x;
cin >> x;
return x;
}
static int a = 0;
void finding(TA* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].print();
a = 1;
}
}
}
void finding(student* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].print();
a = 1;
}
}
}
void finding(teacher* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].print();
a = 1;
}
}
}
void finding(graduate* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].print(); a = 1;
}
}
}
void change(graduate* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].input();
a = 1;
}
}
}
void change(TA* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].input();
a = 1;
}
}
}
void change(teacher* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].input();
a = 1;
}
}
}
void change(student* p1, string nam)
{
int i = 0;
for (; i < 100; i++)
{
if (!p1[i].names.compare(nam)) {
p1[i].input();
a = 1;
}
}
}
int main()
{
TA ta[100];
student st[100];
teacher tc[100];
graduate gr[100];
int nta = 0, nst = 0, ntc = 0, ngr = 0;//统计录了几个数据
int i = 0;
while (1)
{
int x = 0;
cout << "\n功能菜单:1.录入 2.查询 3.更改\n";
cin>>x ;
int kin;
if (x == 1)
{
cout << "请选择你要录入的身份:1.学生2.教师3.研究生4.助教\n";
kin = choose();
if (kin == 1) { st[nst++].input(); }
if (kin == 2) { tc[ntc++].input(); }
if (kin == 3) { gr[ngr++].input(); }
if (kin == 4) { ta[nta++].input(); }
}
if (x == 2)
{
a = 0;
cout << "请输入你要查询的姓名:\n";
string namee; cin >> namee;
string name; finding(ta, namee); finding(tc, namee); finding(gr, namee); finding(st, namee);
if (!a)cout << "查无此人!\n";
}
if (x == 3)
{
a = 0;
cout << "请输入你要更改信息的姓名:\n"; string namee; cin >> namee;
string name; change(ta, namee); change(tc, namee); change(gr, namee); change(st, namee);
if (!a)cout << "查无此人!\n";
}
}
}