C++案例试炼:机房预约系统【附完整代码】

  机房预约系统需求:学校存在几个机房,但是由于大家使用的时间基本都是一样的,所以需要设计一个预约系统来解决这一问题。

身份简介

  在这个系统中会有三类人用到这个机房。

  1. 学生:申请使用机房。
  2. 教师:审核学生的预约申请。
  3. 管理员:给学生、教师创建账号。

机房简介

  机房总共有3间:

  1. 1号机房:最大容量20人。
  2. 2号机房:最多容量50人。
  3. 3号机房:最多容量100人。

申请简介

  • 每周由管理员清空一次申请订单。所以管理员需要给它提供一个清空的能力。
  • 学生可以预约未来一周内的机房使用,预约日期为周一至周五,预约时需要选择预约时段(上午、下午)。
  • 老师来审核预约,依据实际情况审核预约通过或者不通过。

系统具体需求

主界面展示

  • 首先进入系统登录界面,可选登录身份有
  1. 学生
  2. 老师
  3. 管理员
  4. 退出

各子菜单展示

  • 每一个身份都需要进行验证之后,才能进入子菜单
  1. 学生需要输入:学号、姓名、登录密码。
  2. 老师需要输入:职工号、姓名、登录密码。
  3. 管理员需要输入:管理员姓名、登录密码。
学生
  • 学生的具体功能
  1. 申请预约。
  2. 查看自己的预约状态。
  3. 查看全部预约信息以及预约状态。
  4. 取消自身的预约,预约成功或审核中的预约均可取消。
  5. 注销登录。
老师
  • 教师具体功能
  1. 查看全部预约信息以及预约状态。
  2. 对学生的预约进行审核。
  3. 注销登录。
管理员
  • 管理员具体功能
  1. 添加学生或教师的账号,需要检测学生编号或教师职工号是否重复。
  2. 可以选择查看学生或教师的全部信息。
  3. 查看所有机房的信息。
  4. 清空所有机房的信息。
  5. 清空所有预约记录。
  6. 退出登录。

代码逻辑

主逻辑

身分类的共性

  在这个预约系统中总共有三种身份:学生老师管理员。他们都有一些共性,比如像,他们都有用户名和密码。因此可以将其抽象出来作为一个身份的基类identity。除了具有用户名和密码这两个特性之外,每个类都还有一个子菜单界面,并且每个类下面的子菜单是不一样的。

// Base Class of Identity
class Identity{
public:
    virtual void openMenu() = 0; 
    string m_name; // user name
    string m_pwd;  // user passward
}

  所以提供了一个openMenu()的纯虚函数,子类必须要去重写这个纯虚函数。如果对c++中虚函数的概念还不清楚的话,可以参考我的另外一篇文章:C/C++笔试面试基础与进阶(十二)虚函数详解

管理员模块

  学生和老师的账号信息都是有管理员来添加或者删除的。所以我们首先实现管理员模块。

  提供一个全局函数来实现子菜单的内容。

void managerMenu(Identity* &manager){
    while(true){
        // Call the administrator submenu
        manager->openMenu();
        
        // Casting base class pointer to derived class pointer
        Manager* man = (Manager*)manager;
        
        int select = 0;
        if(cin >> select){
            if(select ==  1){
                cout << "add account"  << endl;
                man->addPerson();
            }else if(select == 2){
                cout << "view account" << endl;
                man->showPerson();
            }else if(select == 3){
                cout << "view computer room information" << endl;
                man->showComputer();
            }else if(select == 4){
                cout << "clear reservation record" << endl;
                man->cleanFile();
            }else{
                // Logout

                // Destroys the specified heap object
                delete manager; // 
                cout << "Logout successfully!" << endl;
                return;
            }
        }else{
            std::cout << "managerMenu Invalid input!" << std::endl;
            cin.clear();
        }        
    }
}

  除此之外还需要提供一个去重的操作,当添加新账号时,如果是重复的学生编号,或者是重复的教师职工编号,提示有误!要去除重复的账号,首先要先将学生和教师的账号信息获取到程序中,方可检测。在manager.h中,添加两个容器,用于存放学生和教师的信息。添加一个新的成员函数void initVector()初始化容器。

  管理员还需要查看机房的相关信息,在案例需求中,机房一共有三个,其中1号机房容量20台机器,250台机器,3100台机器。我们可以将信息录入到computerRomm.txt中:

  显示预约,显示预约记录时,需要从文件中获取到所有记录,用来显示,创建预约的类来管理记录以及更新在头文件以及源文件下分别创建orderFile.horderFile.cpp文件。

管理员类

  管理员类主要功能是对学生和老师账户进行管理,查看机房信息以及清空预约记录。管理员类中主要功能有:1. 显示管理员操作的菜单界面;2. 添加账号;3. 查看账号;4. 查看机房信息;5. 清空预约记录。

  在头文件以及源文件下创建manager.hmanager.cpp文件。

  1. manager.h
class Manager :public Identity{
public:
    // Default constructor
    Manager();
    
    // Parameterized constructor, parameter: manager ID, name and password
    Manager(string name, string pwd);
    
    // Menu interface
    virtual void openMenu();
    
    // add Person Information
    void addPerson();
    
    // show Person Information
    void showPerson();
    
    // show computer information
    void showComputer();
    
    // clear the order information
    void cleanFile();
}

  到目前为止我们实现了身份的基类,身份基类的派生类声明派生类的实现

学生模块

  学生模块的主要外层功能逻辑,思路与管理员模块类似:

void studentMenu(Identity* &student){
    while(true){
        student->openMenu();
        
        Student* stu = (Student*)student;
        
        int select = 0;
        
        if(cin >> select){
            if(select == 1){
                // Apply for a reservation
                stu->applyOrder();
                
            }else if(select == 2){
                // View your own reservation
                stu->showMyOrder();
                
            }else if(select == 3){
                // View all reservation
                stu->showAllOrder();
            
            }else if(select == 4){
                // Cancel reservation
                stu->cancelOrder();
            }else{
                delete student;
                cout << "quit successful " << endl;
            }
        }else{
            cout << "Invalid input!" << endl;
            cin.clear();
        }
    }
}

学生类

  有了抽象基类之后,我们就可以来实现派生类:学生类。学生类主要功能是可以通过类中成员函数,实现预约实验室操作。学生类中主要功能有:1. 显示学生操作的菜单界面;2. 申请预约;3. 查看自身预约;4. 查看所有预约;5. 取消预约。

  所以在写这个类的时候,首先第一步,我们需要创建出来这个类。我们需要声明student.hstudent.cpp。分别在头文件夹源文件夹下创建。

  1. student.h
class Student:public Identity{
public:
    // Default constructor
    Student();  
    
    // Parameterized constructor, parameter: student ID, name and password
    Student(int id, string name, string pwd); 
    
    // Menu interface
    virtual void openMenu();
    
    // Apply for a reservation
    void applyOrder();
    
    // View your own reservation
    void showMyOrder();
    
    // View all reservation
    void showAllOrder();
    
    // Cancel reservation
    void cancelOrder();
    
    // Student ID
    int m_Id;
}
  1. 在有参构造函数中,需要读取机房的一些信息;
  2. openMenu函数中提供用于学生选择的菜单界面;在applyOrder中需要实现学生的申请预约操作,需要接收学生的申请日期、申请时间段、以及申请的机房信息;
  3. 然后将申请的信息写入文件中;
  4. showMyOrder函数中,需要对预约信息存储的文件进行读取,然后循环判断学号等于自己学号的时候,输出显示预约信息;
  5. showAllOrder函数中,需要对预约文件夹下存储的信息进行读取并循环输出。

老师模块

  在老师模块中,我们需要对老师的主要功能实现逻辑上的连接:

void teacherMenu(Identity* &teacher) {
	while (true) {
		// Call the teacher submenu
		teacher->openMenu();

		// Casting base class pointer to derived class pointer
		Teacher* tea = (Teacher*)teacher;

		int select = 0;
		cin >> select;

		if (select == 1) {
			// View all reservation
			tea->showALLOrder();
		}
		else if (select == 2) {
			// Review reservation
			tea->validOrder();
		}
		else {
			// Logout
			delete teacher;
			cout << "Logout successful!" << endl;

			return;
		}
	}
}

老师类

  在教师类中,有:1. 老师操作的菜单界面;2. 查看所有预约的功能;3. 审核预约。在头文件以及源文件下我们需要去创建teacher.hteacher.cpp这两个文件。

  1. teacher.h
class Teacher:Identity{
public:
    // Default constructor
    Teacher();
    
    // Parameterized constructor, parameter: student ID, name and password
    Teacher(int empID, string name, string pwd);
    
    // Menu interface
    virtual void openMenu();
    
    // View all reservation
    void showALLOrder();
    
    // check the order
    void validOrder();
    
    int m_EmpId; // teacher ID
}
  1. Teacher的有参构造函数中实现教工信息的IDname以及pwd等参数的初始化;
  2. openMenu中输出给教师的选择菜单界面,主要是两个,输出所有预约和审核预约;
  3. showALLOrder函数中,对存取预约信息的文件进行读取然后输出显示;
  4. validOrder中需要对预约记录一个一个处理。

登录模块

  在进入系统之后,我们有三种身份可以选择。不管用户选择哪个身份,他都需要进行文件的操作。我们可以将所有的文件名定义到一个全局的文件中。

  登录函数需要根据用户的选择,进入不同的身份登录。在main.cpp文件中添加全局函数void LoginIn(string fileName, int type)。参数fileName表示操作的文件名,type表示登录的身份(1代表学生;2代表老师;3代表管理员)。

void LoginIn(string fileName, int type){
    
    // base class pointer pointing to derived object
    Identity* person = NULL;
    
    // read file
    ifstream ifs;
    ifs.open(fileName.c_str(), ios::in);
    
    // determine if the file exists
    if(!ifs.is_open()){
        cout << "file is not exist" << endl;
        ifs.close();
        return;
    }
    
    // Ready For Input Information
    int id = 0;
    string name;
    string pwd;
    
    if(type == 1){ // student login
        cout << "Please Input Your Student ID" << endl;
//        if(){
//        }else{
//        }
        cin >> id;
    }else if(type == 2){ // teacher login
        cout << "Please Input Your Teacher ID" << endl;
        cin >> id;
    }
    
    cout << "Please Input Your User Name" << endl;
    cin >> name;
    
    cout << "Please Input Your PassWard" << endl;
    cin >> pwd;
    
    if(type == 1){ // student login
        
        // ID, name and passward from file
        int fID; 
        string fName;
        string fPwd;
        
        while(ifs >> fID && ifs >> fName && ifs >> fPwd){
            if(fID == id && fName == name && fPwd == pwd){
                cout << "Student login verification success!" << endl;
                person = new Student(id, name, pwd);
                
                // enter student submenu page
                studentMenu(person);
                
                return;
            }
        }
        
        
    }else if(type == 2){ // teacher login
        
        // ID, name and passward from file
        int fID; 
        string fName;
        string fPwd;
        
        while(ifs >> fID && ifs >> fName && ifs >> fPwd){
            if(fID == id && fName == name && fPwd == pwd){
                cout << "Teacher login verification success!" << endl;
                person = new Teacher(id, name, pwd);
                
                // enter Teacher submenu page
                teacherMenu(person);
                
                return;
            }
        }
        
    }else if(type == 3){ // administer login
        
        // name and passward from file
        string fName;
        string fPwd;
        
        while(ifs >> fName && ifs >> fPwd){
            if(fName == name && fPwd == pwd){
                cout << "admin login verification success!" << endl;
                person = new Manager(name, pwd);
                
                // enter Admin submenu page
                managerMenu(person);
                
                return;
            }
        }
    }
    
    cout << "Failed to verify login" << endl;
    
    return;
}
  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值