目录
大家好,我是羽峰,今天要和大家分享的是一个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;
}