学生管理系统
- 一、问题描述
- 二、设计需求及分析
- 三、概要设计
- 四、详细设计
- 五、设计功能的实现(C++语言描述)
- 六、实例测试及运行结果
- 七、实现提示
- 八、UML图
- 九、心得体会
一、问题描述
随着大学规模的不断扩大,有关各种学生信息的数据量也不断增大。学生有本科生、研究生和助教博士生,校方需要对这些学生的信息进行计算机管理。所开发的软件应包括各类学生的添加、修改、删除和查找等功能。考虑到软件的可重用性、可扩展性和可维护性,校方决定采用面向对象的程序设计方法来开发系统。学生信息需要以文件方式保存到计算机硬盘中。另外,系统的用户界面应该尽可能友好,方便用户使用。
源文件开源在:https://github.com/fengqianiqan/C-C-studentSystem
二、设计需求及分析
(1) 使用C++语言开发,充分利用面向对象程序设计的类、对象、继承、封装和多态性等 概念来设计和实现该管理系统。
(2) 设计一个Person(人员)类,考虑到通用性,只抽象出所有类型人员都具有的属性:name(姓名),
id(身份证号),gender(性别),birthday(出生日期)等等。其中“出生日期”为内嵌子对象,是一个Date(日期)类型,Date类具有属性:
year(年),month(月),day(日)。用成员函数实现对人员信息的录入和显示等必要功能操作。
(3) 从Person类派生出Student(学生)类,添加属性: studentNo(学号),schoolName(学校),classIn
(班级)。从Person类派生出Teacher(教师)类,添加属性:teacherNo(教师编号),schoolName(学校),department(部门)。
(4) 从Student类中派生出UnderGraduate(本科生)类,添加属性:major(专业)。从Student类中派生出Graduate(研究生)类,添加属性:direction(研究方向),adviserName(导师姓名)。
(5) 从Graduate类和Teacher类派生出TA(助教博士生)类。 (6) 写程序测试上述各类,看能否正常运行。
(7) 构建必要的辅助类,实现对本科生、研究生和助教博士生的添加、修改、删除、查询管理。
(8) 根据需要定义类的构造函数、析构函数、拷贝构造函数、成员函数。必要时重载函数。
(9) 要求将Person类设置为虚基类,以消除其派生类成员访问的二义性问题(注意在虚基类各级派生类的构造函数实现时调用虚基类的构造函数)。
(10) 要求在Person类中定义虚函数displayDetails(),用于显示当前对象的信息;同时定义虚函数inputData(
),用于从键盘获取当前对象的信息。Person类所有派生类也要定义同名虚函数,使程序可以实现动态多态性。
(11) 用菜单方式设计主控模块程序。 (12) 对程序源代码要给出各部分的详细注释,这也是该题目的考核重点之一。
(13) 用UML语言描述系统用到的类及其关系。
三、概要设计
(1)//日期类型定义
class Date{private:int year;int month;int day;public:Date(Date &d){year = d.year; month = d.month; day = d.day;} //初始化~Date( ){ };void setYear(int y){year = y;}void setMonth(int m){month = m;}void setDay(int d){day = d;}//修改单个属性int getYear( ){return year;}int getMonth( ){return month;}int getDay( ){return day;}//修改单个属性void inputDate(){cout <> year;cout <> month;cout <> day;}//输入各个属性void displayDate(){cout << year << "-" << month << "-" << day << endl;}//输出各个属性};
(2)定义人物及其子类
class 人物{protected:idType id[18]; //编号nameType name[20];//姓名genderType gender[6];//性别属性Type 属性[xxx];Date birthday;//出生日期public:Person();//人的默认构造方法Person(char* sname, char* sid, char* sgender, int y, int m, int d); //人的含参构造~Person(){};void set属性名(char* sname){strcpy(name, sname);}//姓名设置char* getName(){return name;}//获取姓名virtual void inputData();//输入数据virtual void displayDetails(); //显示数据};
(3)各类学生的管理系统
class 某类学生Manager{private:int top = 0;学生Type 学生[100];public:UnderGraduateManager();//读取文件int queryByNo(string sno);void clearStudent();int addStudent(UnderGraduate s);int modifyStudent(string sno);int deleteStudent(string sno);int queryStudent(string sno);void displayAll();void dataManage();void dataSave();void dataRead();~UnderGraduateManager();//写入文件};
四、详细设计
(1)人类型定义
Person::Person(){//默认构造strcpy(属性, "默认值");基类默认构造();birthday = Date(1980, 1, 1);}Person::Person(参数Type 传入参数):基类构造函数(参数Type 传入参数){//自定义构造strcpy(属性, "传入值");}void 类名::inputData(){ //修改或输入数据cout <> name;cout <> id;cout <> gender;…………cout << "birthday: " << endl; birthday.inputDate();}void Person::displayDetails(){//输出数据cout << "属性名: " << 属性 << endl;birthday.displayDate();}
(2)学生管理
某类学生Manager::某类学生Manager(){ //读取数据dataRead();}void 某类学生Manager::dataRead(){某类学生 s;top--;fstream file("文件路径", ios::in); while(1){file.read((char*)&s, sizeof(s));if(!file) break;top++;某类学生[top] = s;}file.close();}
(3)按照序号查询
int 某类学生Manager::queryByNo(string sno){ // 查找,有:返回i, 无: 返回-1for(int i = 0; i <= top; i++)if(某类学生[i].getStudentNo()==sno)return i;return -1;}
(4)删除学生
void 某类学生Manager::clearStudent(){//停止检索最后一个元素,相当于删除元素top=-1;}
(5)增加学生
int 某类学生Manager::addStudent(某类学生 s){//若不存在该元素(return -1),则元素数+1,保存至文件int p = queryByNo(s.getStudentNo());if(p==-1){top++;某类学生[top] = s;dataSave();return 1;}else{cout << "existed!" << endl;return 0;}}
(6)修改数据
int 某类学生Manager::modifyStudent(string sno){//若存在该元素(return != -1),则修改属性,保存至文件int p = queryByNo(sno);if(p == -1){cout << "Not exist!" << endl;return 0;}else{cout << "please input new detials" << endl;某类学生[p].inputData();dataSave();return 1;}}
(7)删除学生
int 某类学生Manager::deleteStudent(string sno){//删除元素,其他元素前移int p = queryByNo(sno);if(p == -1){//返回-1为不存在cout << "Not exist!" << endl;return 0;}else{for(int i = 0; i < top; i++)某类学生[i] = 某类学生[i+1];top--;cout << "Deleted!" << endl;dataSave();return 1;}}
(8)展示该类所有学生信息
void 某类学生Manager::displayAll(){for(int i = 0; i <= top; i++){cout << "The NO." << i << "student's info:" << endl;某类学生[i].displayDetails();}}
(9)保存学生信息
void 某类学生Manager::dataSave(){fstream file("路径名", ios::out);// !for(int i = 0; i <= top; i++){file.write((char*)&某类学生[i], sizeof(某类学生[i]));}file.close();}
五、设计功能的实现(C++语言描述)
/*************************************************Copyright (C), File name: main.cppAuthor: Version: 1.0 Date:Description: 应用程序主函数 *************************************************/#include #include #include "date.h"#include "person.h"#include "student.h"#include "teacher.h"#include "undergraduate.h"#include "graduate.h"#include "ta.h"#include "undergraduateManager.h"using namespace std;int main(int argc, char *argv[]){ int choiceN;UndergraduateManager unMan;cout<<"********************************************************"<<endl;cout<<"*|*||*|*"<<endl;cout<<"*|*|欢迎您使用学生管理系统|*|*"<<endl;cout<<"*|*||*|*"<<endl;cout<<"********************************************************"<<endl;do{cout << "" << endl;cout << " \n \t\t 1:本科生管理 ";cout << " \n \t\t 2:研究生管理";cout << " \n \t\t 3.助教博士生管理 "; cout << " \n \t\t 0:离开"; cout << endl;cout << "" << endl; cout << "请选择:" <> choiceN;switch(choiceN){case 1: unMan.dataManage(); break;case 2://break;case 3://break;default:break;}}while(choiceN!=0);cout<<" **********************************************************"<<endl;cout<<"*|*| 感谢使用学生管理系统|*|*"<<endl;cout<<" **********************************************************\a"<<endl;}/*************************************************Copyright (C),File name: undergraduateManager.hAuthor: Version: 1.0 Date:Description: 本科生管理类 *************************************************/#ifndef UNDERGRADUATE_MANAGER_H#define UNDERGRADUATE_MANAGER_H#include #include #include #include "undergraduate.h"using namespace std;/* Define a Class : UndergraduateManager 本科生管理类*/class UndergraduateManager {private:int top; //记录指针Undergraduate undergraduates[100]; //本科生记录public:UndergraduateManager();//构造函数,将Undergraduate.txt读到undergraduates[]中int queryByNo(string sno);//按本科生号查找 //找到:返回数组下标//没找到:返回-1void clearStudent();//删除所有本科生信息int addStudent(Undergraduate s); //添加本科生,需要先查找是否存在 int modifyStudent(string sno);//修改学生信息 ,需要先查找是否存在int deleteStudent(string sno);//删除本科生,删除前先查找其是否存在 int queryStudent(string sno);//查找本科生,查到则显示,否则提示未查到 void displayAll();//输出所有本科生信息void dataManage(); //本科生库维护void dataSave();void dataRead();~UndergraduateManager();//析构函数,将undergraduates[]写入Undergraduate.txt文件中};//构造函数,将Undergraduate.txt读到undergraduates[]中UndergraduateManager::UndergraduateManager() { dataRead(); } //按本科生号查找//找到:返回数组下标//没找到:返回-1 int UndergraduateManager::queryByNo(string sno){for(int i=0;i<=top;i++)if (undergraduates[i].getStudentNo()==sno) return i;return -1;} //删除所有本科生信息 void UndergraduateManager::clearStudent() { top=-1;}//添加本科生,需要先查找是否存在int UndergraduateManager::addStudent(Undergraduate s) {int p=queryByNo(s.getStudentNo());if (p==-1){top++;undergraduates[top]= s;dataSave();//保存 return 1;}else{cout<此学生已经存在 !<----------"<<endl<<endl;return 0;}}//修改科生,删除前先查找其是否存在int UndergraduateManager::modifyStudent(stringsno) {int p=queryByNo(sno);if (p==-1){cout<此学生不存在 !<----------"<<endl<<endl;return 0;}else{cout << "请输入该生的新信息: " << endl<<endl;undergraduates[p].inputData();dataSave();//保存 return 1;}}//删除本科生,删除前先查找其是否存在 int UndergraduateManager::deleteStudent(string sno){int p=queryByNo(sno);if (p==-1){cout<此学生不存在 !<----------"<<endl<<endl;return 0;}else{for(int i = p; i < top ; i++) undergraduates[i]=undergraduates[i+1];top--;cout <删除完成!<----------" << endl<<endl;dataSave();//保存 return 1;}}//查找科生int UndergraduateManager::queryStudent(string sno) {int p=queryByNo(sno);if (p==-1){cout<此学生不存在 !<----------"<<endl<<endl;return 0;}else{cout<此学生存在:<----------"<<endl<<endl;undergraduates[p].displayDetails();return 1;}}//输出所有本科生信息void UndergraduateManager::displayAll() {for (int i=0;i<=top;i++){cout << "--------第"<< i <<"个学生情况----------" << endl<<endl; undergraduates[i].displayDetails(); } }//析构函数,将undergraduates[]写入Undergraduate.txt文件中UndergraduateManager::~UndergraduateManager(){dataSave();}void UndergraduateManager::dataManage(){int choice=1;string sstudentNo;Undergraduate s;while (choice!=0){cout << "********************************************" << endl; cout << "\t\t本科生维护\n";cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl; cout << "\n \t\t 1:新增 ";cout << "\n \t\t 2:修改 ";cout << "\n \t\t 3:删除 ";cout << "\n \t\t 4:查找 ";cout << "\n \t\t 5:显示 ";cout << "\n \t\t 6:全部删除 "; cout << "\n \t\t 0:退出 " ;cout << endl;cout << "*********************************************" << endl;cout << "请选择:" <> choice;switch (choice){case 1:s.inputData();addStudent(s);break;case 2:cout <> sstudentNo;modifyStudent(sstudentNo);break;case 3:cout <> sstudentNo;deleteStudent(sstudentNo);break;case 4:cout <> sstudentNo;queryStudent(sstudentNo); break;case 5:displayAll();break;case 6:clearStudent();break;default:break; }}}void UndergraduateManager::dataSave()//存储资料函数,将read[]写入Undergraduate.txt文件中{fstream file("Undergraduate.dat",ios::out);for (int i=0;i<=top;i++)file.write((char *)&undergraduates[i],sizeof(undergraduates[i]));file.close();}void UndergraduateManager::dataRead() //构造函数,将Undergraduate.txt读到read[]中{Undergraduate s;top=-1;fstream file("Undergraduate.dat",ios::in);while (1){file.read((char *)&s,sizeof(s));if (!file) break;top++;undergraduates[top]=s;}file.close();}#endif //UNDERGRADUATE_MANAGER_H/*************************************************Copyright (C), File name: date.hAuthor: Version: 1.0 Date Description: 日期类 *************************************************/#ifndef DATE_H#define DATE_H#include using namespace std; /* Define a Class : Date*//* with attributes: year, month, and day, and *//* operations: getYear, getMonth,.... */class Date{private:int year;int month;int day;public:Date(){year = 0; month = 0; day = 0;}Date(int yy,int mm,int dd){year = yy; month = mm; day = dd;}Date(Date& d){year = d.year; month = d.month; day = d.day;}~Date(){}void setYear(int yy){ year = yy;}void setMonth(int mm){ month = mm;}void setDay(int dd){ day = dd;}int getYear(){return year;}int getMonth(){return month;}int getDay(){return day;}void inputDate(){ cout <> year; cout <> month; cout <> day;}void displayDate(){ cout << year << "/" << month << "/" << day << endl; } };#endif //DATE_H/*************************************************Copyright (C),File name: person.hAuthor:Version: 1.0 Date Description: 人员类 *************************************************/#ifndef PERSON_H#define PERSON_H#include #include #include using namespace std;/* Define a Class : Person *//* with attributes: name, id,gender, birthday *//* operations: getName, getId, and setId. *//* person is the base class *///该类为虚基类 class Person{protected: char name[20];//姓名char id[18];//身份证号char gender[2];//性别Date birthday;//出生日期public:Person(); Person(char* sname, char* sid, char* sgender,int yy,int mm ,int dd); ~Person(){} void setName(char* sname){ strcpy(name,sname); }char* getName(){ return name; } void setId(char* sid){ strcpy(id,sid); }char* getId(){ return id;} void setGender(char* sgender){ strcpy(gender,sgender); } char* getGender(){ return gender; } void setBirthday(Date d){ birthday = d; } Date getBirthday() { return birthday; } virtual void inputData();//输入数据virtual void displayDetails();//显示数据 };Person::Person(){ strcpy(name,"NA"); strcpy(gender,"男"); strcpy(id,"000"); //注意:这里没有给birthday赋值,系统会调用其默认构造函数//也可以//Date d(1980,1,1); //birthday = d; }Person::Person(char* sname, char* sid, char* sgender,int yy,int mm ,int dd):birthday(yy,mm,dd){ strcpy(name,sname); strcpy(id,sid); strcpy(gender,sgender);}void Person::inputData(){ cout <> name ; cout <> id ; cout <> gender ; cout << "出生日期:" << endl;birthday.inputDate(); }void Person::displayDetails(){ cout << "姓名:" <<name <<endl; cout << "身份证号:" <<id <<endl; cout << "性别:" <<gender<<endl; cout << "出生日期:";birthday.displayDate(); }#endif //PERSON_H/*************************************************Copyright (C), File name: teacher.hAuthor: Version: 1.0 Date: Description: 教师类 *************************************************/#ifndef TEACHER_H#define TEACHER_H#include #include #include #include "person.h"using namespace std;/* Define a Class : Teacher *//* with attributes: *//* operations: */class Teacher: virtual public Person{protected: char teacherNo[5];//教师编号char schoolName[20];//学校名称char department[20];//部门public:Teacher(); Teacher(char* sname, char* sid, char* sgender,int yy,int mm ,int dd ,char* steacherNo,char* sschool,char* sdepartment); ~Teacher(){} void setTeacherNo(char* sno){ strcpy(teacherNo,sno); }char* getTeacherNo(){ return teacherNo;} void setSchoolName(char* sschool){ strcpy(schoolName,sschool); }char* getSchoolName(){ return schoolName; } void setDepartment(char* sdepartment){ strcpy(department,sdepartment); }char* getDepartment(){ return department; } virtual void inputData();//输入数据virtual void displayDetails();//显示数据};Teacher::Teacher():Person(){ strcpy(teacherNo,"001"); strcpy(schoolName,"defaultSchoolName"); strcpy(department,"defaultDepartment");}Teacher::Teacher(char* sname, char* sid, char* sgender,int yy,int mm ,int dd,char* steacherNo,char* sschool,char* sdepartment):Person(sname,sid,sgender,yy,mm,dd){ strcpy(teacherNo,steacherNo); strcpy(schoolName,sschool); strcpy(department,sdepartment); }void Teacher::inputData(){ Person::inputData(); cout <> teacherNo ; cout <>schoolName ; cout <>department ;}void Teacher::displayDetails(){ Person::displayDetails(); cout << "教师编号:" << teacherNo <<endl; cout << "学校:" << schoolName <<endl; cout << "部门:" << department << endl;}#endif //TEACHER_H#pragma once/*************************************************Copyright (C) File name: student.hAuthor:Version: 1.0 Date: 2022.5.30Description: 学生类*************************************************/#ifndef STUDENT_H#define STUDENT_H#include #include #include #include "person.h"using namespace std;/* Define a Class : Student *//* with attributes: *//* operations: */class Student : virtual public Person{protected:char studentNo[15];//学生编号 char schoolName[20];//学校名称 char classIn[20];//班级 public:Student();Student(char* sname, char* sid, char* sgender, int yy, int mm, int dd, char* sstudentNo, char* sschool, char* sclassIn);~Student() {}void setStudentNo(char* sno) { strcpy_s(studentNo, sno); }char* getStudentNo() { return studentNo; }void setSchoolName(char* sschool) { strcpy_s(schoolName, sschool); }char* getSchoolName() { return schoolName; }void setClassIn(char* sdepartment) { strcpy_s(classIn, sdepartment); }char* getClassIn() { return classIn; }virtual void inputData();//输入数据 virtual void displayDetails();//显示数据};Student::Student() :Person(){strcpy_s(studentNo, "001");strcpy_s(schoolName, "defaultSchoolName");strcpy_s(classIn, "defaultClassIn");}Student::Student(char* sname, char* sid, char* sgender, int yy, int mm, int dd, char* sstudentNo, char* sschool, char* sclassIn):Person(sname, sid, sgender, yy, mm, dd){strcpy_s(studentNo, sstudentNo);strcpy_s(schoolName, sschool);strcpy_s(classIn, sclassIn);}void Student::inputData(){Person::inputData();cout <> studentNo;cout <> schoolName;cout <> classIn;}void Student::displayDetails(){Person::displayDetails();cout << "学生学号:" << studentNo << endl;cout << "学校:" << schoolName << endl;cout << "班级:" << classIn << endl;}#endif //STUDENT_H#pragma once/*************************************************Copyright (C), File name: graduate.hAuthor: Version: 1.0 Date: 2022.5.30Description: 研究生类*************************************************/#ifndef GRADUATE_H#define GRADUATE_H#include #include #include #include "student.h"using namespace std;/* Define a Class : Graduate *//* with attributes: *//* operations: */class Graduate : virtual public Student{protected:char direction[20];// 研究方向char adviserName[20];// 导师姓名public:Graduate();Graduate(char* sname, char* sid, char* sgender, int yy, int mm, int dd, char* sstudentNo, char* sschool, char* sclassIn, char* direction ,char* adviserName);~Graduate() {}void setDirection(char* sno) { strcpy_s(direction, sno); }char* getDirection() { return direction; }void setAdviserName(char* sno) { strcpy_s(adviserName, sno); }char* getAdviserName() { return adviserName; }virtual void inputData();//输入数据 virtual void displayDetails();//显示数据};Graduate::Graduate() :Student(){strcpy_s(direction, "defaultDirection");strcpy_s(adviserName, "defaultAdviserName");}Graduate::Graduate(char* sname, char* sid, char* sgender, int yy, int mm, int dd, char* sstudentNo, char* sschool, char* sclassIn, char* sdirection, char* sadviserName): Student(sname, sid, sgender, yy, mm, dd, sstudentNo, sschool, sclassIn){strcpy_s(direction, sdirection);strcpy_s(adviserName, sadviserName);}void Graduate::inputData(){Student::inputData();cout <> direction;cout <> adviserName;}void Graduate::displayDetails(){Student::displayDetails();cout << "研究方向:" << direction << endl;cout << "导师姓名:" << adviserName << endl;}#endif //GRADUATE_H#pragma once/*************************************************Copyright (C), File name: undergraduate.hAuthor:Version: 1.0 Date: 2022.5.30Description: 本科生类*************************************************/#ifndef UNDERGRADUATE_H#define UNDERGRADUATE_H#include #include #include #include "student.h"using namespace std;/* Define a Class : Udergraduate *//* with attributes: *//* operations: */class Undergraduate : virtual public Student{protected:char major[20];// 主修专业public:Undergraduate();Undergraduate(char* sname, char* sid, char* sgender, int yy, int mm, int dd, char* sstudentNo, char* sschool, char* sclassIn, char* smajor);~Undergraduate() {}void setMajor(char* sno) { strcpy_s(major, sno); }char* getMajor() { return major; }virtual void inputData();//输入数据 virtual void displayDetails();//显示数据};Undergraduate::Undergraduate() :Student(){strcpy_s(major, "defaultMajor");}Undergraduate::Undergraduate(char* sname, char* sid, char* sgender, int yy, int mm, int dd, char* sstudentNo, char* sschool, char* sclassIn, char* smajor):Student(sname, sid, sgender, yy, mm, dd ,sstudentNo, sschool, sclassIn){strcpy_s(major, smajor);}void Undergraduate::inputData(){Student::inputData();cout <> major;}void Undergraduate::displayDetails(){Student::displayDetails();cout << "主修专业:" << major << endl;}#endif //UNDERGRADUATE_H#pragma once/*************************************************Copyright (C), File name: ta.hAuthor:Version: 1.0 Date: 2022.5.30Description: 助教博士生类*************************************************/#ifndef TA_H#define TA_H#include #include #include #include"teacher.h"#include"graduate.h"using namespace std;/* Define a Class : Ta *//* with attributes: *//* operations: */class Ta : virtual public Graduate,virtual public Teacher{public:Ta();Ta(char* sname, char* sid, char* sgender, int yy, int mm, int dd, char* sstudentNo,char* sschool, char* sclassIn, char* sdirection, char* sadviserName, char* steacherNo,char* sdepartment);~Ta() {}virtual void inputData();//输入数据 virtual void displayDetails();//显示数据};Ta::Ta() :Graduate(),Teacher(){}Ta::Ta(char* sname, char* sid, char* sgender, int yy, int mm, int dd , char* sstudentNo, char* sschool, char* sclassIn, char* sdirection, char* sadviserName,char* steacherNo, char* sdepartment): Student(sname, sid, sgender, yy, mm, dd, sstudentNo, sschool, sclassIn){strcpy_s(teacherNo, steacherNo);strcpy_s(Teacher::schoolName, sschool);strcpy_s(department, sdepartment);strcpy_s(direction, sdirection);strcpy_s(adviserName, sadviserName);}void Ta::inputData(){Graduate::inputData();cout <> teacherNo;//cout <> Teacher::schoolName;cout <> department;}void Ta::displayDetails(){Graduate::displayDetails();cout << "教师编号:" << teacherNo << endl;//cout << "学校:" << Teacher::schoolName << endl;cout << "部门:" << department << endl;}#endif //TA_H
六、实例测试及运行结果
七、实现提示
进入程序主界面后:
输入1:进入本科生管理系统
输入2:进入研究生管理系统
输入3:进入助教博士生管理系统
输入0:退出
八、UML图
九、心得体会
Main程序中:通过一个while循环,识别像目前的序号,实现相应的功能。实例化UndergraduateManager、Graduate Manager、TaManager三个类,对应主函数的switch序号,将实例化对象的dataMAnager函数打出实现本层功能。
UnderGraduateManager类:dataMAnager()函数用于while switch循环,分别实现新增、删除、修改、查找、显示、全部删除等功能,在本类中构造其他相应的函数实现这些功能,完成本层功能。
Graduate Manager类与上类类似;
TaManager类与上类类似;
其余各个人员类,按照新增的成员和类继承实现相应的构造函数、虚函数inputData、displayData即可。