一、实验内容、实验任务和目的

根据题目要求设计一款具有以下功能的公司职员信息管理系统:

  1. 使用要求的类与对象。
  2. 增删查显。

二、实验步骤、过程、程序的数据结构和主要算法说明或流程

主程序的框架还是和之前几次实验一样,都是利用死循环实现菜单的重复响应。将题目要求的类复制过来后,进行了一定的修改,如将员工各项参数的数据类型由char数组、int改成了统一的string,方便简化输入与输入合法性的判断;对于临时指针Sta,因为没找到合适的地方使用,所以删了;对于无需公开的类成员变量,改成了私有成员;统一了一下变量命名规则,不然对于同义的变量,有些长有些短、有些大写有些小写,容易搞混,现规则为函数输入变量为小写,类内成员变量为首字母大写,长度都为3~4字母单词缩写。

因为自己比较习惯看类内定义的代码,所以写的类成员函数都是类内定义的。

对于大括号语句块内只有两句的情况,看着比较占位置,所以对于有返回值的语句,采用了逗号表达式精简至一行。

由于Company类中有多个成员函数需要查找一个职工是否存在及其位置,所以将FindStaff的返回值改为了整数型来用于多义返回,-1表示未找到,大于等于0则表示找到的add数组下标(其实也可以等价理解为类自定义的一种指针),所以对于需要查找职工的类功能函数,直接将其输入定义为专门用于接收FindStaff返回值即可,以此来减少代码重复率,提高函数的复用率。

对于查找,只需要for循环枚举职工号即可。对于删除只需delete指定下标的add指针对象,再将后面的指针依次往前移即可。

三、程序的整体结构

由于是面向对象程序,整体结构较为复杂,所以没有详细的流程图。
程序大致可以表示为如下情况:
流程图

四、程序的完整代码

#include<iostream>
#include<iomanip>
using namespace std;
const string welcome = "\n\
    --------------------------------------\n\
    *                                    *\n\
    *    欢迎进入公司职工信息管理程序    *\n\
    *                                    *\n\
    --------------------------------------\n\
    |                                    |\n\
    |           请选择您的操作           |\n\
    |                                    |\n\
    |    1. 增加职工信息                 |\n\
    |    2. 查找职工信息                 |\n\
    |    3. 显示所有职工信息             |\n\
    |    4. 删除职工信息                 |\n\
    |    0. 退出                         |\n\
    |                                    |\n\
    --------------------------------------\n\
\n\
请输入序号(0-4):";
class Staff{
public:
    string No; // 职员号
    Staff(){
        Name = No = Dep = Wage = Pos = "";
    };
    ~Staff(){};
    Staff(string name, string no, string dep, string wage, string pos){
        Name = name;
        No = no;
        Dep = dep;
        Wage = wage;
        Pos = pos;
    };
    void Display(){
        cout << left << setw(8) << Name << setw(8) << No << setw(8) << Dep << setw(8) << Wage << setw(8) << Pos << endl;
    };
private:
    string Name; // 姓名
    string Dep; // 职员所在的部门
    string Wage; // 工资
    string Pos; // 职位
};
class Company{
public:
    Company(){
        count = 0;
    };
    ~Company(){
        for(int i = 0; i < count; i++)
            delete add[i];
    };
    bool AddStaff(string name, string no, string dep, string wage, string pos){ // 添加职工
        if(count < 30)
            return (add[count++] = new Staff(name, no, dep, wage, pos)), true;
        else
            return false;
    };
    void DeleteStaff(int p){ // 删除职工
        delete add[p];
        for(int i = p; i < count - 1; i++)
            add[i] = add[i + 1];
        count--;
    };
    int FindStaff(string no){ // 查找职工
        int flag = -1;
        for(int i = 0; i < count; i++)
            if(add[i]->No == no){
                flag = i;
                break;
            }
        return flag;
    };
    void DispAll(){ // 显示所有职工
        if(count > 0){
            cout << endl << left << setw(8) << "姓名" << setw(8) << "职工号" << setw(8) << "部门" << setw(8) << "工资" << setw(8) << "职务" << endl;
            for(int i = 0; i < count; i++)
                DispOne(i);
            cout << endl;
        }else
            cout << endl << "无员工" << endl << endl;
    };
    void DispOne(int p){
        add[p]->Display();
    };
private:
    int count;
    Staff *add[30]; // 对象指针数组
};
int main(){
    system("color F0");
    system("mode con cols=46"); // 截图时取消注释,使窗口大小便于在实验报告中排版
    Company nmdwsm;
    while(true){
        cout << welcome;
        int cmd = -1;
        cin >> cmd;
        // 输入验证
        while(cmd < 0 || cmd > 4){
            cout << "功能序号无效,请重新输入:";
            cin >> cmd;
        }
        // 主体程序
        if(cmd == 1){
            string cmdcmd[5] = {"姓名", "号", "部门", "工资", "职位"};
            for(int i = 0; i < 5; i++){
                cout << "\n请输入职工" + cmdcmd[i] + ":";
                cin >> cmdcmd[i];
            }
            if(nmdwsm.FindStaff(cmdcmd[1]) != -1)
                cout << endl << "职工号已存在" << endl << endl;
            else if(!nmdwsm.AddStaff(cmdcmd[0], cmdcmd[1], cmdcmd[2], cmdcmd[3], cmdcmd[4]))
                cout << endl << "添加失败" << endl << endl;
            else
                cout << endl << "添加成功" << endl << endl;
            system("pause");
        }else if(cmd == 2){
            cout << "\n请输入要查找的职工号:";
            string cmdcmd = "";
            cin >> cmdcmd;
            int ret = nmdwsm.FindStaff(cmdcmd);
            if(ret == -1)
                cout << endl << "找不到这个人" << endl << endl;
            else{
                cout << endl << left << setw(8) << "姓名" << setw(8) << "职工号" << setw(8) << "部门" << setw(8) << "工资" << setw(8) << "职务" << endl;
                nmdwsm.DispOne(ret);
                cout << endl;
            }
            system("pause");
        }else if(cmd == 3){
            // 主体程序
            nmdwsm.DispAll();
            system("pause");
        }else if(cmd == 4){
            cout << "\n请输入要删除的职工号:";
            string cmdcmd = "";
            cin >> cmdcmd;
            int ret = nmdwsm.FindStaff(cmdcmd);
            if(ret == -1)
                cout << endl << "找不到这个人" << endl << endl;
            else{
                nmdwsm.DeleteStaff(ret);
                cout << endl << "删除成功" << endl << endl;
            }
            system("pause");
        }else if(cmd == 0){
            break;
        }
        system("cls");
    }
    cout << "感谢使用!\n";
    system("pause");
    return 0;
}

五、测试结果

所有功能皆可正常实现,未发现明显bug。
菜单界面
增加职工信息界面
增加职工信息界面(已存在)
查找职工信息界面
查找职工信息界面(不存在)
显示职工信息界面
删除职工信息界面
删除职工信息界面(不存在)
显示职工信息界面(不存在)

六、分析与讨论

本次实验主要考察类与对象的基础知识,没有难度较大的要求,只要理清了类的逻辑即可写出程序。