c++初学者动手实践项目:职工系统管理(上)

Posted 羽峰码字

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++初学者动手实践项目:职工系统管理(上)相关的知识,希望对你有一定的参考价值。

目录

项目简介

职工管理系统项目代码及注释

0 退出管理系统

WorkerManager.h

WorkerManager.cpp

主函数“职工管理系统.cpp”

增加职工信息

worker.h 基类

员工类 employee.h

员工employee.cpp

经理类manager.h 

经理manager.cpp

老板类 boss.h

老板boss.cpp

添加职工

员工信息的文件交互

写文件

读文件

第一种情况:第一次使用,文件未创建

第二种情况文件存在,但是数据被用户清空了

第三种文件存在,并且保存职工的所有数据


大家好,我是羽峰,今天要和大家分享的是一个c++上手项目:职工系统管理,通过这个项目,大家可以更好的对c++面向对象和文件操作有一个更深入的了解。

项目简介

项目环境:mac vscode.

公司职工分为三类:普通员工、经理、老板,显示信息时需要显示职工编号、职工姓名、职工岗位、以及职责。

普通员工:完成经理交给对任务

经理:完成老板的任务,并下发任务给员工

老板:管理公司所有业务

管理系统中需要实现的功能如下:

  • 0 退出管理程序

  • 1 增加职工信息

  • 2 显示职工信息

  • 3 删除离职员工

  • 4 修改职工信息

  • 5 查找职工信息

  • 6 按照编号排序

  • 7 清空所有文档

本篇文章主要实现了0-2中的功能,但这是本项目的基础,涉及到了多态,文件操作等C++基础知识,希望通过本篇文章的实践,你可以更好的理解多态,文件操作等操作。

 

职工管理系统项目代码及注释

0 退出管理系统

 

显示菜单和退出管理系统比较容易,直接创建一个WorkerManager.h,WorkerManager.cpp, 还有个主程序“职工管理系统.cpp”即可。代码和注释如下:

WorkerManager.h

#pragma once //防止头文件重复包含
#include <iostream> //包含输入输出流头文件
#include<string>
using namespace std; // 使用标准命名空间
​
class WorkerManager
{
private:
    /* data */
public:
    //构造函数
    WorkerManager(/* args */);
    //展示菜单
    void Show_Menu(); 
    //0 退出系统
    void ExitSystem();
    //析构函数
    ~WorkerManager();
};

WorkerManager.cpp

#include "WorkerManager.h"
​
// 构造函数
WorkerManager::WorkerManager(/* args */)
{
}
// 显示菜单
void WorkerManager::Show_Menu()
{
    cout << "**************************************************" << endl;
    cout << "*****************欢迎使用职工管理系统****************" << endl;
    cout << "*****************0 退出程序************************" << endl;
    cout << "*****************1 增加职工信息*********************" << endl;
    cout << "*****************2 显示职工信息*********************" << endl;
    cout << "*****************3 删除离职职工*********************" << endl;
    cout << "*****************4 修改职工信息*********************" << endl;
    cout << "*****************5 查找职工信息*********************" << endl;
    cout << "*****************6 按照编号排序*********************" << endl;
    cout << "*****************7 清空所有文档*********************" << endl;
    cout << "**************************************************" << endl;
    cout << endl;
}
​
// 退出系统
void WorkerManager::ExitSystem()
{
    cout << "欢迎下次使用" << endl;
​
    exit(0);
}
// 析构函数
WorkerManager::~WorkerManager()
{
}


主函数“职工管理系统.cpp”

#include<iostream>
using namespace std;
#include "WorkerManager.h"
#include "WorkerManager.cpp"
​
int main()
{
    WorkerManager wm;
    int choice = 0;
    while (true)
    {
        /* code */
        wm.Show_Menu();
        cout << "请输入您的选择" << endl;
        cin >> choice;// 用来存储用户选项
        switch (choice)
        {
        case 0: //退出系统
            /* code */
            wm.ExitSystem();
            break;
        case 1: //增加职工信息
            /* code */
            break;
        case 2: //显示职工信息
            /* code */  
            break;           
        case 3: //删除离职职工
            /* code */
            break;
        case 4: //修改职工信息
            /* code */
            break;
        case 5: //查找职工信息
            /* code */
            break;
        case 6: //按照编号排序
            /* code */
            break;
        case 7: //清空所有文档
            /* code */
            break;
        
        default:
            break;
        }
    }
    return 0;
}


 

增加职工信息

 

这一步需要使用多态来实现

首先创建职工类的抽象类

职工的分类为普通员工,经理,老板。将三种职工抽象到一个类(worker)中,利用多态来管理不同职工种类。

worker.h 基类

#pragma once //防止头文件重复包含
#include <iostream> //包含输入输出流头文件
#include<string>
using namespace std; // 使用标准命名空间
​
//1 职工抽象基类
class Worker
{
private:
    /* data */
public:
    Worker(/* args */) {}
    //显示个人信息
    virtual void showInfo() = 0;
    //获取岗位名称
    virtual string getDeptName() = 0;
    
    int m_ID; //职工编号
    string m_Name; // 职工姓名
    int m_Deptid; //职工所在部门名称编号
    
    virtual ~Worker() {}
};

 

员工类 employee.h

#pragma once //防止头文件重复包含
#include <iostream> //包含输入输出流头文件
#include<string>
#include "Worker.h"
using namespace std; // 使用标准命名空间
​
class Employee : public Worker
{
private:
    /* data */
public:
    Employee(int id, string name, int dId);
    //显示个人信息
    virtual void showInfo();
    //获取岗位名称
    virtual string getDeptName();
    virtual ~Employee() {}
};

 

员工employee.cpp

#include "employee.h"
​
Employee::Employee(int id, string name, int dId)
{
    this -> m_ID = id;
    this -> m_Name = name;
    this -> m_Deptid = dId;
}
​
void Employee::showInfo()
{
    cout <<"职工编号" << this->m_ID << endl;
    cout <<"职工姓名" << this->m_Name << endl;
    cout << "岗位" << this->getDeptName() << endl;
    cout << "岗位职责:完成经理交给的任务"<< endl;     
}
​
string Employee::getDeptName()
{
    return string("员工");
}

 

经理类manager.h 

#pragma once //防止头文件重复包含
#include <iostream> //包含输入输出流头文件
#include<string>
#include "Worker.h"
using namespace std; // 使用标准命名空间
​
class Manager : public Worker
{
private:
    /* data */
public:
    Manager(int id, string name, int dId);
    //显示个人信息
    virtual void showInfo();
    //获取岗位名称
    virtual string getDeptName();
    virtual ~Manager() {}
};

 

经理manager.cpp

#include "manager.h"
​
Manager::Manager(int id, string name, int dId)
{
    this -> m_ID = id;
    this -> m_Name = name;
    this -> m_Deptid = dId;
}
​
void Manager::showInfo()
{
    cout <<"职工编号" << this->m_ID << endl;
    cout <<"职工姓名" << this->m_Name << endl;
    cout << "岗位" << this->getDeptName() << endl;
    cout << "岗位职责:完成老板交给的任务,并下发任务给员工"<< endl;     
}
​
string Manager::getDeptName()
{
    return string("经理");
}

 

老板类 boss.h

#pragma once //防止头文件重复包含
#include <iostream> //包含输入输出流头文件
#include<string>
#include "Worker.h"
using namespace std; // 使用标准命名空间
​
class Boss : public Worker
{
private:
    /* data */
public:
    Boss(int id, string name, int dId);
    //显示个人信息
    virtual void showInfo();
    //获取岗位名称
    virtual string getDeptName();
    virtual ~Boss() {}
};

 

老板boss.cpp

#include "boss.h"
​
Boss::Boss(int id, string name, int dId)
{
    this -> m_ID = id;
    this -> m_Name = name;
    this -> m_Deptid = dId;
}
​
void Boss::showInfo()
{
    cout <<"职工编号" << this->m_ID << endl;
    cout <<"职工姓名" << this->m_Name << endl;
    cout << "岗位" << this->getDeptName() << endl;
    cout << "岗位职责:管理公司所有事物"<< endl;     
}
​
string Boss::getDeptName()
{
    return string("总裁");
}

 

“职工系统.cpp”

#include<iostream>
#include "WorkerManager.h"
#include "WorkerManager.cpp"
#include "Worker.h"
#include "employee.h"
#include "employee.cpp"
#include "manager.h"
#include "manager.cpp"
#include "boss.h"
#include "boss.cpp"
​
using namespace std;
​
void test_work()
{
    Worker *worker = NULL;
    worker = new Employee(1, "张三", 1);
    worker->showInfo();
    delete worker;
​
    worker = new Manager(2, "李四", 2);
    worker->showInfo();
    delete worker;
​
    worker = new Boss(3, "王5", 3);
    worker->showInfo();
    delete worker;
​
}
​
int main()
{
    WorkerManager wm;
    int choice = 0;
    while (true)
    {
        /* code */
        wm.Show_Menu();
        cout << "请输入您的选择" << endl;
        cin >> choice;// 用来存储用户选项
        switch (choice)
        {
        case 0: //退出系统
            /* code */
            wm.ExitSystem();
            break;
        case 1: //增加职工信息
            /* code */
            test_work();
            break;
        case 2: //显示职工信息
            /* code */
            cout << "增加职工信息" << endl;
            break;
        case 3: //删除离职职工
            /* code */
            break;
        case 4: //修改职工信息
            /* code */
            break;
        case 5: //查找职工信息
            /* code */
            break;
        case 6: //按照编号排序
            /* code */
            break;
        case 7: //清空所有文档
            /* code */
            break;
        
        default:
            break;
        }
    }
    return 0;
}

 

 

添加职工

功能描述:批量添加职工,并保存到文件中

功能分析:

用户在批量创建时,可能会创建不同种类的职工。

如果想讲所有不同种类的员工都放入到一个数组中,可以将所有员工的指针维护到一个数组中。

如果想在程序中维护这个不定长度的数组,可以将数组创建到堆区,并利用Worker**的指针维护。

 

当把文件删除时,测试就会多显示一行,文件不存在。

 

第二种情况文件存在,但是数据被用户清空了

修改workerManager.cpp中的构造函数代码

// 构造函数
WorkerManager::WorkerManager(/* args */)
{
  
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
    //文件不存在的情况
    if(!ifs.is_open())
    {
        cout<< "文件不存在" << endl;
        this -> m_EmpNum = 0; //初始化人数
        this -> m_FileIsEmpty  = true; //初始化文件为空的标志
        this -> m_EmpArray = NULL; // 初始化数组
        ifs.close(); //关闭文件
        return;
    }
    // 文件存在,并且没有记录任何东西
    char ch;
    ifs >> ch;
    if (ifs.eof())
    {
        cout << "文件为空!" << endl;
        this -> m_EmpNum = 0; //初始化人数
        this -> m_FileIsEmpty  = true; //初始化文件为空的标志
        this -> m_EmpArray = NULL; // 初始化数组
        ifs.close(); //关闭文件
        return;
    }
}

 

并且应该在workerManager.cpp中的void WorkerManager::Add_Emp()函数中追加一个this-> m_FileIsEmpty = false;,当有员工被添加时,这个职工判断标志为false;追加位置如下

         //释放原来空间
        delete[] this -> m_EmpArray;
        //更改新空间的指向
        this -> m_EmpArray = newSpace;
        //更新新的个数
        this -> m_EmpNum = newSize;
        // 更新职工不为空的标志
        this-> m_FileIsEmpty = false;

 

第三种文件存在,并且保存职工的所有数据

在workerManager.h中添加成员函数

//统计人数
int get_EmpNum();

 

然后在workerManager.cpp中定义该成员函数

int WorkerManager::get_EmpNum()
{
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
    int id;
    string name;
    int did;
    int num = 0;
    while (ifs >> id && ifs >> name && ifs >> did )
    {
        /* code */
        //记录人数
        num ++ ;
    }
    ifs.close();
    return num;
}

 

并在构造函数中添加

    // 第三种情况文件存在,并且有数据
    int num = this->get_EmpNum();
    cout <<"职工人数为"<< num << endl;
    this->m_EmpNum = num;

 

接下来就是根据职工的数据初始化workerManager中的Worker **m_EmpArray指针。

在WorkerManager.h中添加成员函数 void init_Emp();

    //初始化员工
    void init_Emp();

 

在WorkerManager.cpp中实现这个成员函数

//初始化员工
void WorkerManager::init_Emp()
{
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
​
    int id;
    string name;
    int did;
​
    int index = 0;
    while (ifs >>id && ifs >> name &&ifs >> did)
    {
        /* code */
        Worker *worker = NULL;
        //根据不同部门ID创建不同对象
        if (did == 1)//1 普通员工
        {
            worker = new Employee(id, name, did);
        }
        else if (did == 2) // 经理
        {
            worker = new Manager(id, name, did);
        }
        else 
        {
            worker = new Boss(id, name, did);
        }
        //存放在数组中
        this -> m_EmpArray[index] = worker;
        index++;
    }
}

 

并在构造函数中调用,

//开辟空间
    this ->m_EmpArray = new Worker*[this->m_EmpNum];
    //将文件中的数据存储到数组中
    this -> init_Emp();
    for (int i = 0; i < this->m_EmpNum; i++)
    {
        /* code */
        cout << "职工编号: "<< this->m_EmpArray[i]->m_ID << endl;
        cout << "姓名: "<< this->m_EmpArray[i]->m_Name << endl;
        cout << "部门编号: "<< this->m_EmpArray[i]->m_Deptid<< endl;
    }

 

for中是测试,此时输出的是

正在上传…重新上传取消

此时的WorkerManager.h如下

#pragma once //防止头文件重复包含
#include <iostream> //包含输入输出流头文件
#include<string>
using namespace std; // 使用标准命名空间
#include"Worker.h"
#include<fstream>
#define FILENAME "empfile.txt"
​
​
class WorkerManager
{
private:
    /* data */
public:
    //构造函数
    WorkerManager(/* args */);
    //记录文件中的人数个数
    int m_EmpNum;
    //标志文件是否为空
    bool m_FileIsEmpty;
    //员工数组指针
    Worker ** m_EmpArray;
​
    //展示菜单
    void Show_Menu(); 
    //0 退出系统
    void ExitSystem();
    //1 增加职工
    void Add_Emp();
    //保存文件
    void filesave();
    //统计人数
    int get_EmpNum();
    //初始化员工
    void init_Emp();
    //析构函数
    ~WorkerManager();
};

 

此时的WorkerManager.cpp如下

#include "WorkerManager.h"
#include "Worker.h"
#include "employee.h"
#include "employee.cpp"
#include "manager.h"
#include "manager.cpp"
#include "boss.h"
#include "boss.cpp"
​
// 构造函数
WorkerManager::WorkerManager(/* args */)
{
  
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
    //第一种情况 文件不存在的情况
    if(!ifs.is_open())
    {
        cout<< "文件不存在" << endl;
        this -> m_EmpNum = 0; //初始化人数
        this -> m_FileIsEmpty  = true; //初始化文件为空的标志
        this -> m_EmpArray = NULL; // 初始化数组
        ifs.close(); //关闭文件
        return;
    }
    // 第二种情况 文件存在,并且没有记录任何东西
    char ch;
    ifs >> ch;
    if (ifs.eof())
    {
        cout << "文件为空!" << endl;
        this -> m_EmpNum = 0; //初始化人数
        this -> m_FileIsEmpty  = true; //初始化文件为空的标志
        this -> m_EmpArray = NULL; // 初始化数组
        ifs.close(); //关闭文件
        return;
    }
    
    // 第三种情况文件存在,并且有数据
    int num = this->get_EmpNum();
    cout <<"职工人数为"<< num << endl;
    this->m_EmpNum = num;
    
    //开辟空间
    this ->m_EmpArray = new Worker*[this->m_EmpNum];
    //将文件中的数据存储到数组中
    this -> init_Emp();
    for (int i = 0; i < this->m_EmpNum; i++)
    {
        /* code */
        cout << "职工编号: "<< this->m_EmpArray[i]->m_ID << endl;
        cout << "姓名: "<< this->m_EmpArray[i]->m_Name << endl;
        cout << "部门编号: "<< this->m_EmpArray[i]->m_Deptid<< endl;
    }
    
}
​
// 显示菜单
void WorkerManager::Show_Menu()
{
    cout << "**************************************************" << endl;
    cout << "*****************欢迎使用职工管理系统****************" << endl;
    cout << "*****************0 退出程序************************" << endl;
    cout << "*****************1 增加职工信息*********************" << endl;
    cout << "*****************2 显示职工信息*********************" << endl;
    cout << "*****************3 删除离职职工*********************" << endl;
    cout << "*****************4 修改职工信息*********************" << endl;
    cout << "*****************5 查找职工信息*********************" << endl;
    cout << "*****************6 按照编号排序*********************" << endl;
    cout << "*****************7 清空所有文档*********************" << endl;
    cout << "**************************************************" << endl;
    cout << endl;
}
​
// 退出系统
void WorkerManager::ExitSystem()
{
    cout << "欢迎下次使用" << endl;
​
    exit(0);
}
void WorkerManager::Add_Emp()
{
    cout << "请输入增加职工数量" << endl;
    int addNum = 0;
    cin >> addNum;
    if (addNum > 0)
    {
        //计算新空间大小
        int newSize = this -> m_EmpNum + addNum;
        //开辟新空间
        Worker ** newSpace = new Worker *[newSize];
​
        //将原空间下的内容复制到新空间下
        if (this -> m_EmpArray != NULL)
        {
            for (int i = 0; i < this->m_EmpNum; i++)
            {
                /* code */
                newSpace[i] = this ->m_EmpArray[i];
            }
            
        }
        //输入新数据
        for (int i = 0; i < addNum; i++)
        {
            int id;
            string name;
            int dSelect;
            cout << "请输入第" << i+1 <<"个新员工的编号: " << endl;
            cin >> id;
​
            cout << "请输入第" << i+1 << "个新员工姓名: " << endl;
            cin >> name;
​
            cout << "请选择该职工的岗位: " << endl;
            cout <<"1 普通员工" << endl;
            cout <<"2 经理" << endl;
            cout <<"3 老板" << endl;
​
            cin >> dSelect;
​
            Worker * worker = NULL;
            switch (dSelect)
            {
            case 1:
                /* code */
                worker = new Employee(id,name,1);
                break;
            case 2:
                /* code */
                worker = new Manager(id,name,2);
                break;
            case 3:
                /* code */
                worker = new Boss(id,name,3);
                break;
            default:
                break;
            }
​
            newSpace[this->m_EmpNum+i] = worker;
        }
​
        //释放原来空间
        delete[] this -> m_EmpArray;
        //更改新空间的指向
        this -> m_EmpArray = newSpace;
        //更新新的个数
        this -> m_EmpNum = newSize;
        // 更新职工不为空的标志
        this-> m_FileIsEmpty = false;
        // 保存在文件中
        this->filesave();
        //提示信息
        cout << "成功添加" << addNum << "名新职工" << endl;
​
    }
    else
    {
        cout << "输入有误" << endl;
    }
}
//保存功能实现
void WorkerManager::filesave()
{
    ofstream ofs;
    ofs.open(FILENAME, ios::out);
​
    //将每个人的数据写进文件中
    for (int i = 0; i < this->m_EmpNum; i++)
    {
        ofs << this->m_EmpArray[i]->m_ID << " "
            << this->m_EmpArray[i]->m_Name<< " "
            << this->m_EmpArray[i]->m_Deptid << endl;
    }
​
    ofs.close();
}
int WorkerManager::get_EmpNum()
{
    ifstream ifs;
    ifs.open(FILENAME, ios::in); // 打开文件读
    int id;
    string name;
    int did;
    int num = 0;
    while (ifs >> id && ifs >> name && ifs >> did )
    {
        /* code */
        //记录人数
        num ++ ;
    }
    ifs.close();
    return num;
}
//初始化员工
void WorkerManager::init_Emp()
{
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
​
    int id;
    string name;
    int did;
​
    int index = 0;
    while (ifs >>id && ifs >> name &&ifs >> did)
    {
        /* code */
        Worker *worker = NULL;
        //根据不同部门ID创建不同对象
        if (did == 1)//1 普通员工
        {
            worker = new Employee(id, name, did);
        }
        else if (did == 2) // 经理
        {
            worker = new Manager(id, name, did);
        }
        else 
        {
            worker = new Boss(id, name, did);
        }
        //存放在数组中
        this -> m_EmpArray[index] = worker;
        index++;
    }
    ifs.close(); //关闭文件
}
// 析构函数
WorkerManager::~WorkerManager()
{
    if (this -> m_EmpArray != NULL)
    {
        delete[] this -> m_EmpArray;
        this-> m_EmpArray = NULL;
    }
}

 

此时的“职工管理系统.cpp”为

#include<iostream>
#include "WorkerManager.h"
#include "WorkerManager.cpp"
using namespace std;
​
int main()
{
    WorkerManager wm;
    int choice = 0;
    while (true)
    {
        /* code */
        wm.Show_Menu();
        cout << "请输入您的选择" << endl;
        cin >> choice;// 用来存储用户选项
        switch (choice)
        {
        case 0: //退出系统
            /* code */
            wm.ExitSystem();
            break;
        case 1: //增加职工信息
            /* code */
            wm.Add_Emp();
            break;
        case 2: //显示职工信息
            /* code */
            cout << "增加职工信息" << endl;
            break;
        case 3: //删除离职职工
            /* code */
            break;
        case 4: //修改职工信息
            /* code */
            break;
        case 5: //查找职工信息
            /* code */
            break;
        case 6: //按照编号排序
            /* code */
            break;
        case 7: //清空所有文档
            /* code */
            break;
        
        default:
            break;
        }
    }
    return 0;
}

以上是关于c++初学者动手实践项目:职工系统管理(上)的主要内容,如果未能解决你的问题,请参考以下文章

c++上手项目:职工系统管理(下)

C++项目实战:基于多态的职工管理系统(源码)

C++实战基于多态的企业职工系统

黑马程序员C++教程从0到1入门编程--职工管理系统

C++C++实现职工管理系统

c++ 职工管理系统 代码汇总 分开简易讲解全文思路