职工信息管理系统完善版(C++面向对象实现)
Posted joker D888
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了职工信息管理系统完善版(C++面向对象实现)相关的知识,希望对你有一定的参考价值。
文章目录
基于多态的职工管理系统
功能实现:
1.系统以菜单方式与按键输入进行交互工作;
2.职工信息添加功能:
(1)单个录入; (2)批量录入。
3.职工信息删除功能:
(1)按编号删除; (2)按姓名删除。
4.职工信息查找功能:
(1)按编号查找; (2)按姓名查找。
5.职工信息修改功能:
(1)单项信息修改; (2)全项信息修改。
6.职工信息排序功能:
(1)升序; (2)降序。
7.清除数据、显示全部职工信息功能。
整个程序分为worker.cpp、worker.h、WorkerManager.cpp、WorkerManager.h、职工管理系统.cpp五个文件编写。
- worker文件主要为公司普通员工,经理,总裁三种职位创建编写职工类,完成基本职位基础信息构建。
- WorkerManager文件创建了管理类,用类成员函数实现系统所需的各种功能。
- 职工管理系统文件则是对整体功能进行实现。
worker.h内容
#pragma once
#include<iostream>
using namespace std;
//创建一个抽象职工类,保留公共特性,重写个人信息
class Worker
{
public:
//显示个人信息
virtual void ShowInfo() = 0;
//职工编号
int m_Id;
//姓名
string m_Name;
//部门编号
int m_dId;
};
//其中的dId为部门编号,1普通职工,2经理,3老板
//普通职工
class Employee :public Worker
{
public:
//构造函数以传入的职工编号,姓名来初始化成员变量
Employee(int id, string name);
//重写个人信息函数
virtual void ShowInfo();
};
//经理
class Manager :public Worker
{
public:
//构造函数以传入的职工编号,姓名来初始化成员变量
Manager(int id, string name);
//重写个人信息函数
virtual void ShowInfo();
};
//老板
class Boss :public Worker
{
public:
//构造函数以传入的职工编号,姓名来初始化成员变量
Boss(int id, string name);
//重写个人信息函数
virtual void ShowInfo();
};
worker.cpp内容
#include"worker.h"
Employee::Employee(int id, string name)
{
this->m_Id = id;
this->m_Name = name;
this->m_dId = 1;
}
void Employee::ShowInfo()
{
cout << "职工编号: " << m_Id
<< "\\t职工姓名:" << m_Name
<< "\\t岗位:普通职工"
<< "\\t岗位职责: 完成经理交给的任务" << endl;
}
Manager::Manager(int id, string name)
{
this->m_Id = id;
this->m_Name = name;
this->m_dId = 2;
}
void Manager::ShowInfo()
{
cout << "职工编号: " << m_Id
<< "\\t职工姓名:" << m_Name
<< "\\t岗位:经理"
<< "\\t岗位职责: 完成老板交给的任务,并下发任务给员工" << endl;
}
Boss::Boss(int id, string name)
{
this->m_Id = id;
this->m_Name = name;
this->m_dId = 3;
}
void Boss::ShowInfo()
{
cout << "职工编号: " << m_Id
<< "\\t职工姓名:" << m_Name
<< "\\t岗位:总裁"
<< "\\t岗位职责: 管理公司所有事务" << endl;
}
WorkerManager.h内容
#pragma once
#include<iostream>
using namespace std;
#include"worker.h"
#include<fstream>
#define FILENAME "empFile.txt"//职工信息存储文档
//创建一个管理类,有能够实现具有增删查改,显示,排序,清空等功能的成员函数
class WorkerManager
{
public:
//构造函数
WorkerManager();
//析构函数
~WorkerManager();
//菜单
void Menu();
//退出
void Exit();
//扩容
void Expand(int n);
//单个增加员工
void AddEmp();
//批量增加员工
void BatchAddEmp();
//显示公司员工信息
void ShowEmp();
//保存数据到本地
void Save();
//从文档中获取员工数目
int GetEmpNum();
//初始化员工数组
void InitEmp();
//删除员工
void DelEmp();
//按照职工编号判断职工是否存在,若存在返回职工在数组中位置,不存在返回-1
int IsExist(int id);
//查找员工信息
void FindEmp();
//修改员工信息
void ModEmp();
//按员工序号排序可升可降
void SortEmp();
//清空文件数据
void CleanFile();
public:
//员工数组的指针
Worker** m_EmpArray;//用于存储职工信息
//容量
int m_size;
//当前员工人数
int m_num;
//标志文件是否为空
bool m_FileIsEmpty;
};
WorkerManager.cpp内容
#include"WorkerManager.h"
//构造函数
WorkerManager::WorkerManager()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
//文件不存在
if (!ifs.is_open())
{
this->m_num = 0;
this->m_size = 1;
this->m_EmpArray = new Worker*[this->m_size];
this->m_FileIsEmpty = true;
ifs.close();
return;
}
//文件存在但数据为空
char ch;
ifs >> ch;
if (ifs.eof())
{
this->m_num = 0;
this->m_size = 1;
this->m_EmpArray = new Worker * [this->m_size];
this->m_FileIsEmpty = true;
ifs.close();
return;
}
this->m_num = this->GetEmpNum();
//根据职工数初始化数组容积
this->m_size = this->m_num;
this->m_EmpArray = new Worker * [this->m_size];
WorkerManager::InitEmp();
}
//析构函数
WorkerManager::~WorkerManager()
{
if (this->m_EmpArray != NULL)
{
for (int i = 0; i < this->m_num; i++)
{
if (this->m_EmpArray[i] != NULL)
{
delete this->m_EmpArray[i];
}
}
this->m_num = 0;
delete[] this->m_EmpArray;
this->m_EmpArray = NULL;
this->m_FileIsEmpty = true;
}
}
//菜单
void WorkerManager::Menu()
{
cout << "##################################################" << endl;
cout << "######## #########" << endl;
cout << "######## 0.退出 #########" << endl;
cout << "######## 1.添加职工 2.批量添加 #########" << endl;
cout << "######## 3.删除职工 4.查找职工 #########" << endl;
cout << "######## 5.职员变更 6.编号排序 #########" << endl;
cout << "######## 7.清除数据 8.显示全部信息 #########" << endl;
cout << "######## #########" << endl;
cout << "##################################################" << endl;
}
void WorkerManager::Expand(int n = 1)
{
//默认扩容两倍,可根据实际进行动态扩容
int multiple = 2;
if (n > this->m_size)
{
multiple = (n / m_size) + 1;
}
Worker** newSpace = new Worker * [this->m_size *multiple ];
if (newSpace == NULL)
{
cout << "扩容失败!" << endl;
exit(0);
}
for (int i = 0; i < this->m_num; i++)
{
newSpace[i] = this->m_EmpArray[i];
}
//修该容量
this->m_size *= multiple;
//释放原有空间
delete[] this->m_EmpArray;
//指向新开辟的空间
this->m_EmpArray = newSpace;
}
//单个增加员工
void WorkerManager::AddEmp()
{
//满了,按原来的2倍扩容
if (this->m_num == this->m_size)
{
WorkerManager::Expand();
}
int id = 0;
bool flag = true;
while (flag)
{
cout << "请输入员工编号:" << endl;
cin >> id;
//判断编号是否已存在
if (-1 == IsExist(id))
{
flag = false;
}
else
{
cout << "编号已存在,请仔细确认!" << endl;
}
}
cout << "请输入员工姓名:" << endl;
string name;
cin >> name;
cout << "请选择员工职位:" << endl;
cout << "1.普通员工\\t2.经理\\t\\t3.总裁" << endl;
int choice = 0;
cin >> choice;
Worker* worker=NULL;
//对比上版,上版没有对1,2,3三中数字做有效判断,造成输入非此三种数据时,会导致无法录入员工信息
//在此对输入的选择做有效性判断,只有当选择是这3种中的其中一种,程序才可继续运行
while (choice != 1 && choice != 2 && choice != 3)
{
cout << "输入有误,请重新选择:" << endl;
cin >> choice;
}
//根据输入信息创建对应员工信息
switch (choice)
{
case 1:
worker = new Employee(id, name);
break;
case 2:
worker = new Manager(id, name);
break;
case 3:
worker = new Boss(id, name);
break;
default:
break;
}
m_EmpArray[this->m_num] = worker;
//当前人数++
this->m_num++;
this->Save();
this->m_FileIsEmpty = false;
cout << "添加成功!" << endl;
}
void WorkerManager::BatchAddEmp()
{
cout << "请输入要增加的员工数目:" << endl;
int n;
cin >> n;
//不够装,扩容
if (this->m_num + n > this->m_size)
{
this->Expand(n);
}
for (int i = 0; i < n; i++)
{
cout << "开始录入第" << i+1 << "个人的信息" << endl;
this->AddEmp();
}
cout << "全部信息录入完成!" << endl;
system("pause");
system("cls");
}
//显示员工信息
void WorkerManager::ShowEmp()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
system("pause");
system("cls");
return;
}
cout << "-------------------------员工信息如下--------------------------" << endl << endl;;
for (int i = 0; i < this->m_num; i++)
{
this->m_EmpArray[i]->ShowInfo();
}
cout<<endl << "--------------------------------------------------------------" << endl;
system("pause");
system("cls");
}
void WorkerManager::Save()
{
ofstream ofs;
ofs.open(FILENAME, ios::out);
for (int i = 0; i < this->m_num; i++)
{
ofs << this->m_EmpArray[i]->m_Id << " "
<< this->m_EmpArray[i]->m_Name << " "
<< this->m_EmpArray[i]->m_dId << endl;
}
ofs.close();
}
int WorkerManager::GetEmpNum()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int id;
string name;
int dId;
int num = 0;
while (ifs >> id && ifs >> name && ifs >> dId)
num++;
ifs.close();
return num;
}
void WorkerManager::InitEmp()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int id;
string name;
int dId;
int index = 0;
while (ifs >> id && ifs >> name && ifs >> dId)
{
Worker* worker = NULL;
if (dId == 1)
{
worker = new Employee(id, name);
}
else if (dId == 2)
{
worker = new Manager(id, name);
}
else if (dId == 3)
{
worker = new Boss(id, name);
}
this->m_EmpArray[index] = worker;
index++;
}
}
void WorkerManager::DelEmp()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
system("pause");
system("cls");
return;
}
cout << "您是要按编号还是按照姓名删除?(1.编号 2.姓名)" << endl;
int opt = 0;
cin >> opt;
while (opt != 1 && opt != 2)
{
cout << "输入有误,请重新输入:" << endl;
cin >> opt;
}
//按编号删除
if (1 == opt)
{
cout << "请输入删除员工的编号:" << endl;
int id = 0;
cin >> id;
int index = this->IsExist(id);
if (-1 == index)
{
cout << "查无此人" << endl;
system("pause");
system("cls");
return;
}
cout << "确定删除此人信息吗?(1.Yes 2.No)?" << endl;
this->m_EmpArray[index]->ShowInfo();
int choice = 0;
cin >> choice;
while (choice != 1 && choice != 2)
{
cout << "输入有误,请重新输入:" << endl;
cin >> choice;
}
if (2 == choice)
{
cout << "取消删除!" << endl;
}
//数据前移,实现覆盖删除
if (1 == choice)
{
for (int i = index; i < this->m_num - 1; i++)
{
this->m_EmpArray[i] = this->m_EmpArray[i + 1];
}
this->m_num--;
this->Save();
cout << "删除成功!" << endl;
}
}
//按姓名删除
if (2 == opt)
{
string name;
int index = 0;//确认删除员工的下标
int sum = 0;//同名人数
int* arr = new int[this->m_num];//储存同名人的编号
int j = 0;
cout << "请输入员工的姓名:" << endl;
cin >> name;
cout << "-------------------------信息如下----------------------------" << endl << endl;
for (int i = 0; i < this->m_num; i++)
{
if (this->m_EmpArray[i]->m_Name == name)
{
this->m_EmpArray[i]->ShowInfo();
arr[j++] = this->m_EmpArray[i]->m_Id;
sum++;
index = i;
}
}
cout<<endl;
if (sum > 1)//多人同名的情况,对index定位到要删除的人的下标
{
int id;
cout << "共查到" << sum << "条同名信息,请选择要删除的编号:" << endl;
cin >> id;
//对输入的编号做判断,检查是否是上面显示出来的同名的人的编号
while (true)
{
int i = 0;
for ( i = 0; i < j; i++)
{
if (arr[i] == id)
break;
}
if (i < j)
break;
else
{
cout << "选择有误,请重新选择:" << endl;
cin >> id;
}
}
index = this->IsExist(id);
}
cout << "确定删除此人信息吗?(1.Yes 2.No)?" << endl;
this->m_EmpArray[index]->ShowInfo();
int choice = 0;
cin >> choice;
while (choice != 1 && choice != 2)
{
cout << "输入有误,请重新输入:" << endl;
cin >> choice;
}
if (2 == choice)
{
cout << "取消删除!" << endl;
}
if (1 == choice)
{
for (int i = index; i < this->m_num - 1; i++)
{
this->m_EmpArray[i] = this->m_EmpArray[i + 1];
}
this->m_num--;
this->Save();
cout << "删除成功!" << endl;
}
delete[] arr;//释放
}
system("pause");
system("cls");
}
int WorkerManager::IsExist(int id)
{
for (int i = 0; i < this->m_num; i++)
{
if (this->m_EmpArray[i]->m_Id == id)
{
return i;
}
}
return -1;
}
void WorkerManager::FindEmp()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
system("pause");
system("cls");
return;
}
cout << "您是要按照编号还是按照姓名查找?(1.编号 2.姓名)" << endl;
int choice = 0;
cin >> choice;
while (choice != 1 && choice != 2)
{
cout << "输入有误,请重新输入:" << endl;
cin >> choice;
}
if (1 == choice)
{
cout << "请输入员工的编号:" << endl;
int id = 0;
cin >> id;
int index = this->IsExist(id);
if (-1 == index)
{
cout << "查无此人" << endl;
system("pause");
system("cls");
return;
}
cout << "-------------------------信息如下----------------------------" << endl << endl;
this->m_EmpArray[index]->ShowInfo();
}
if (2 == choice)
{
cout << "请输入员工的姓名:" << endl;
string name;
int id = 0;//如果有同名,再用编号查找
int sum = 0;//同名人数
int* arr = new int[this->m_num];//储存同名人的编号
int j = 0;
cin >> name;
cout << "-------------------------信息如下----------------------------" << endl << endl;
for (int i = 0; i < this->m_num; i++)
{
if (this->m_EmpArray[i]->m_Name == name)
{
this->m_EmpArray[i]->ShowInfo();
arr[j++] = this->m_EmpArray[i]->m_Id;
sum++;
}
}
if (sum > 1)
{
cout << "共查到" << sum << "条同名信息,请选择要查看的编号:" << endl;
cin >> id;
//对输入的编号做判断,检查是否是上面显示出来的同名的人的编号
while (true)
{
int i = 0;
for ( i = 0; i < j; i++)
{
if (arr[i] == id)
break;
}
if (i < j)
break;
else
{
cout << "选择有误,请重新选择:" << endl;
cin >> id;
}
}
int index = this->IsExist(id);
cout << "此人信息如下:" << endl;
this->m_EmpArray[index]->ShowInfo();
}
delete[] arr;//释放
}
system("pause");
system("cls");
}
void WorkerManager::ModEmp()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
system("pause");
system("cls");
return;
}
cout << "请输入你要修改的员工的编号:" << endl;
cout << "(若不清楚员工的编号,可退出利用姓名查找功能查询编号后再进行修改:0.退出修改 1.继续修改 ) " << endl;
int choice = 0;
cin >> choice;
while (choice != 0 && choice != 1)
{
cout << "输入有误,请重新输入:" << endl;
cin >> choice;
}
if (0 == choice)
{
cout << "退出修改!" << endl;
}
if (1 == choice)
{
int id = 0;
cout << "请输入修改的员工编号:" << endl;
cin >> id;
int index = this->IsExist(id);
if (-1 == index)
{
cout << "查无此人" << endl;
}
else
{
cout << "此人信息如下:" << endl;
this->m_EmpArray[index]->ShowInfo();
cout << "请选择修改的信息:(单选:1.编号 2.姓名 3.职位 4.全部信息 )" << endl;
int opt = 0;
cin >> opt;
while (opt != 1 && opt != 2 && opt != 3 && opt != 4)
{
cout << "输入有误,请重新输入:" << endl;
cin >> opt;
}
Worker* worker = NULL;
int oldDId = this->m_EmpArray[index]->m_dId;
int oldId = this->m_EmpArray[index]->m_Id;
string oldName = this->m_EmpArray[index]->m_Name;
int newId = oldId;
string newName = oldName;
int newDId = oldDId;
if (1 == opt)
{
cout << "请输入新编号:" << endl;
cin >> newId;
}
else if (2 == opt)
{
cout << "请输入新姓名:" << endl;
cin >> newName;
}
else if (3 == opt)
{
cout << "请选择新职位:(1.普通员工 2.经理 3.总裁)" << endl;
cin >> newDId;
}
else if (4 == opt)
{
cout << "请输入新编号:" << endl;
cin >> newId;
cout << "请输入新姓名:" << endl;
cin >> newName;
cout << "请选择新职位:(1.普通员工 2.经理 3.总裁)" << endl;
cin >> newDId;
}
//将new信息初始化赋值为old信息,将以上4个相似重复代码简而为一
switch (newDId)
{
case 1:
worker = new Employee(newId, newName);
break;
case 2:
worker = new Manager(newId,newName);
break;
case 3:
worker = new Boss(newId, newName);
break;
default:
break;
}
//释放旧数据空间
delete this->m_EmpArray[index];
//指向新空间
this->m_EmpArray[index] = worker;
cout << "修改成功!" << endl;
//保存到文档
this->Save();
}
}
system("pause");
system("cls");
}
void WorkerManager::SortEmp()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
system("pause");
system("cls");
return;
}
cout << "请选择排序方式:(1.升序 2.降序)" << endl;
int choice = 0;
cin >> choice;
while (choice != 1 && choice != 2)
{
cout << "输出有误,请重新输入:" << endl;
cin >> choice;
}
//选择排序法
for (int i = 0; i < m_num; i++)
{
int index = i;
for (int j = i + 1; j < m_num; j++)
{
if (1 == choice)//升序
{
if (this->m_EmpArray[j]->m_Id < this->m_EmpArray[index]->m_Id)
{
index = j;
}
}
else
{
if (this->m_EmpArray[j]->m_Id > this->m_EmpArray[index]->m_Id)
{
index = j;
}
}
}
if (i != index)
{
Worker* tmp = m_EmpArray[i];
m_EmpArray[i] = m_EmpArray[index];
m_EmpArray[index] = tmp;
}
}
this->Save();
cout << "排序成功,排序后信息如下" << endl;
this->ShowEmp();
}
void WorkerManager::CleanFile()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
system("pause");
system("cls");
return;
}
cout << "确定清空?(1.确认 2.返回)" << endl;
int choice = 0;
cin >> choice;
while (1 != choice && 2 != choice)
{
cout << "输出有误,请重新输入:" << endl;
cin >> choice;
}
if (1 == choice)
{
//打开模式 ios::trunc 如果存在删除文件并重新创建
ofstream ofs(FILENAME, ios::trunc);
ofs.close();
if (this->m_EmpArray != NULL)
{
for (int i = 0; i < this->m_num; i++)
{
if (this->m_EmpArray[i] != NULL)
{
delete this->m_EmpArray[i];
}
}
this->m_num = 0;
delete[] m_EmpArray;
this->m_EmpArray = NULL;
this->m_FileIsEmpty = true;
}
cout << "清空成功!" << endl;
}
system("pause");
system("cls");
}
//退出
void WorkerManager::Exit()
{
cout << "退出系统,欢迎下次使用!" << endl;
system("pause");
exit(0);
}
职工管理系统.cpp内容
#include"WorkerManager.h"
#include"worker.h"
void test01()
{
WorkerManager wm;
int choice = 0;
while (true)
{
wm.Menu();
cout << "请输入您的选择:" << endl;
cin >> choice;
switch (choice)
{
case 0:
wm.Exit();
break;
case 1:
wm.AddEmp();
system("pause");//因批量增加员工函数中连续使用到此函数,若清屏操作放入函数内会影响BatchAddEmp()批量增加函数的使用体验
system("cls");//故出此下策将清屏操作剥离函数,影响些许可读性
break;
case 2:
wm.BatchAddEmp();
break;
case 3:
wm.DelEmp();
break;
case 4:
wm.FindEmp();
break;
case 5:
wm.ModEmp();
break;
case 6:
wm.SortEmp();
break;
case 7:
wm.CleanFile();
break;
case 8:
wm.ShowEmp();
break;
default:
break;
}
}
}
int main(void)
{
test01();
return 0;
}
代码块解释:
- 读/存数据
借助ofstream、ifstream对文本文件进行读写,进而实现职工信息数据的保存和读写。
- Worker** m_EmpAdbrray员工数组的指针
因三种职位属于不同类的职工,要想将所有不同种类的员工都放到一个数组中,则可以将所有员工的指针维护到一个数组中,将数组创建到堆区,并利用Worker** 指针维护。
- 添加职工模块
添加前需检查数组空间是否已满,若已满,则按默认照原空间容量的两倍进行扩容,然后根据用户输入信息创建对应员工信息并用Worker*指针接受,随后添加到数组即可。
- IsExist成员函数
通过遍历数组查找编号,返回数组下标,未找到返回-1。在增删查改功能中都需要用到,故将此代码块单独封装为一个函数。
- 删除、查找职工模块
删除模块通过数据前移覆盖删除,若按编号删除,因编号做了防重操作,所以根据编号所删除的人员是唯一的。若按姓名删除,可能出现多人重名的情况,那么就要遍历数组,将重名的人的信息都输出出来,再让用户输入对应此人的编号,完成删除。
查找模块与删除模块相似,只是没有了数据前移删除操作。
- 修改职工模块
可以对单个信息项或全部信息修改,利用两套职工信息变量,old信息记录原来信息,new记录要替换的信息,且全部new信息初始化为old信息,然后根据用户的选择对new变量进行赋值,可能赋值了某个new变量(单项信息修改),也可能对所有new变量都进行了赋值,但最后都只用根据new信息创建新的职工信息,替换原数据即可。结合代码更易理解。
- 清空模块、析构函数
通过ofstream ofs(FILENAME, ios::trunc);语句对数据文本做清空操作,清空后即可对员工数组进行释放。析构函数也会每次在程序结束前对堆区内存空间进行释放。
细节说明
- 该程序每次对用户的选择输入都会做有效性判断,防止用户手误造成程序出现意想不到的错误。
- 考虑到了删除功能中可能出现多人同名的情况。
- 程序会在适当的地方做清屏操纵只保留菜单,使界面简单明了。
- 程序也对可能出现的问题作出了文字提示,如:文件不存在或数据为空。
- 程序逻辑也较为完善,在某些关键操作中如删除和清空功能中,会进行二次确认。
最后:
此职工管理系统为学习C++面向对象后所做练习,旨在提高对所需内容理解使用,可能会与实际操作有些出入。
如代码出错,或描述有误,欢迎指出。
以上是关于职工信息管理系统完善版(C++面向对象实现)的主要内容,如果未能解决你的问题,请参考以下文章