文章目录
- 一、创建管理类及菜单功能实现
- 二、创建职工抽象类
- 三、退出管理程序
- 四、增加职工信息
- 五、读写文件操作
- 六、显示职工信息
- 七、删除职工信息
- 八、修改职工信息
- 九、查找职工信息
- 十、对职工信息排序
- 十一、清空文件内容
- 十二、工程文件构成
本案例中利用C++实现一个基于多态的职工管理系统。公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名以及职工岗位。
该管理系统需要具备如下功能:
退出管理程序:退出当前管理系统;
增加职工信息:可以实现批量添加职工信息的功能,并将信息写入到文件中,职工信息包括职工编号、姓名、部门编号;
显示职工信息:显示公司内部所有职工的信息;
删除职工信息:按照编号删除指定的职工信息;
修改职工信息:根据编号修改职工的信息;
查找职工信息:按照职工的编号或者职工的姓名查找相关的人员信息;
对职工信息排序:根据职工编号进行排序,排序规则可以由用户指定;
清空文件内容:清空文件中记录的所有职工信息,但在清空前需要再次确认,防止误删。
一、创建管理类及菜单功能实现
在写代码之前,先在Visual Studio中创建一个项目,然后新建一个C++文件。
管理类完成的功能主要有:与用户的沟通菜单界面;对职工增删改查的操作;与文件的读写交互。
为了文件之间功能清晰,分别创建头文件和C++文件用来创建管理类,如下图所示。
WorkerManager.h头文件中暂时包括下面的内容。
#pragma once //防止头文件重复包含
#include <iostream>
using namespace std;
class WorkerManager
{
public:
WorkerManager(); //构造函数
void show_menu(); //显示菜单函数的声明
~WorkerManager(); //析构函数
};
WorkerManager.cpp文件中包含显示菜单函数的实现。
#include "workerManager.h"
WorkerManager::WorkerManager()
{
}
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;
}
WorkerManager::~WorkerManager()
{
}
main.cpp文件中简单的实例化一个管理类对象,然后调用菜单显示函数。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "workerManager.h"
int main()
{
WorkerManager wm; //实例化一个对象
wm.show_menu(); //调用成员函数显示菜单
system("pause");
return 0;
}
有以上代码之后,运行程序之后就可以显示菜单了,如下图所示。
后面各个功能的实现只需要往里面添加函数就可以了。
二、创建职工抽象类
职工分为普通员工、经理、老板,写一个通用的父类,里面包含员工编号、员工姓名、员工所在部门编号,然后分别创建普通员工、经理和老板类继承父类,重写里面相应的函数。
创建一个worker.h头文件,在里面创建职工抽象类,然后分别写子类继承抽象类重写其成员函数。
#pragma once //防止头文件重复包含
#include <iostream>
#include <string>
using namespace std;
class Worker
{
public:
//成员方法
virtual void show_info() = 0; //显示员工信息的纯虚函数
virtual string get_dep() = 0; //获取员工部门的纯虚函数
//成员属性
int worker_id; //员工编号
string name; //员工姓名
int dep_id; //员工部门编号
};
class Employee : public Worker //普通职工类
{
public:
Employee(int worker_id,string name,int dep_id)
{
this->worker_id = worker_id;
this->name = name;
this->dep_id = dep_id;
}
void show_info() //显示员工信息的函数实现
{
cout<<"职工编号:"<<worker_id<<"\t职工姓名:"<<name<<"\t职工岗位:"<<get_dep()<<endl;
}
string get_dep() //获取员工部门的函数实现
{
return "普通员工";
}
};
class Manager : public Worker //经理类
{
public:
Manager(int worker_id,string name,int dep_id)
{
this->worker_id = worker_id;
this->name = name;
this->dep_id = dep_id;
}
void show_info() //显示员工信息的函数实现
{
cout<<"职工编号:"<<worker_id<<"\t职工姓名:"<<name<<"\t职工岗位:"<<get_dep()<<endl;
}
string get_dep() //获取员工部门的函数实现
{
return "经理";
}
};
class Boss : public Worker //老板类
{
public:
Boss(int worker_id,string name,int dep_id)
{
this->worker_id = worker_id;
this->name = name;
this->dep_id = dep_id;
}
void show_info() //显示员工信息的函数实现
{
cout<<"职工编号:"<<worker_id<<"\t职工姓名:"<<name<<"\t职工岗位:"<<get_dep()<<endl;
}
string get_dep() //获取员工部门的函数实现
{
return "老板";
}
};
在main.cpp中继承该头文件,使用如下代码进行测试。
Worker *w = new Employee(1,"张三",1);
w->show_info();
delete w;
w = new Manager(2,"李四",2);
w->show_info();
delete w;
w = new Boss(3,"王五",3);
w->show_info();
delete w;
测试结果如下图所示。
三、退出管理程序
退出管理系统就是在用户输入0之后退出系统,同样的先在管理类中声明函数,然后在相应的C++文件中实现函数,然后在main函数中通过实例化的对象调用函数退出管理程序。
退出管理程序的函数实现如下。
void WorkerManager::exit_system() //退出系统函数的实现
{
cout<<"欢迎下次继续使用!"<<endl;
system("pause"); //按任意键继续
exit(0); //退出程序
}
主函数中根据用户输入的数字决定接下来要进行的操作。
int main()
{
WorkerManager wm; //实例化一个对象
int menu_choice = 0; //用户菜单选择
while(1)
{
wm.show_menu(); //调用成员函数显示菜单
cout<<"请输入您要操作的菜单编号:";
cin>>menu_choice;
switch(menu_choice)
{
case 0: //退出管理程序
wm.exit_system();
break;
case 1: //增加职工信息
break;
case 2: //显示职工信息
break;
case 3: //删除职工信息
break;
case 4: //修改职工信息
break;
case 5: //查找职工信息
break;
case 6: //按照选择排序
break;
case 7: //清空所有信息
break;
default:
system("cls"); //清屏操作
break;
}
}
system("pause");
return 0;
}
程序运行结果如下图所示。
四、增加职工信息
可以批量增加职工信息,职工信息需要保存到文件中。
用户在批量创建时,可能会创建不同种类的职工,如果要将不同种类的员工信息存入到一个数组中,可以将所有职工的指针维护到一个数组里。如果想在程序中维护不定长度的数组,可以将数组创建到堆区,并利用Worker **的指针维护。
在WorkerManager.cpp文件中添加下面的代码增加职工信息,在添加新职工前需要先判断要添加的职工编号是否已经存在。
void WorkerManager::add_employee() //添加职工信息函数的实现
{
cout<<"请输入要添加职工的数量:";
int add_num=0;
cin>>add_num;
if(add_num > 0)
{
int newsize = this->Num + add_num; //新空间的数组大小
Worker **newspace = new Worker*[newsize]; //开辟新空间
//如果原来的数组不为空就进行拷贝
if(this->w_arr != NULL)
{
for(int i=0;i<this->Num;i++)
{
newspace[i] = this->w_arr[i]; //将原数组中的数据拷贝到扩展后的新数组中
}
}
//批量添加职工信息
for(int i=0;i<add_num;i++)
{
int w_id;
string name;
int d_id;
cout<<"请输入第"<<i+1<<"个职工的职工编号:";
cin>>w_id;
while(1) //根据职工编号判断职工信息是否已经存在
{
int j;
for(j=0;j<this->Num+i;j++)
{
if(w_id == newspace[j]->worker_id)
{
break;
}
}
if(j==this->Num+i) //没有重复的职工编号
{
break;
}
else
{
cout<<"编号为"<<w_id<<"的职工信息已存在!"<<endl;
cout<<"请重新输入第"<<i+1<<"个职工的职工编号:";
cin>>w_id;
}
}
cout<<"请输入第"<<i+1<<"个职工的职工姓名:";
cin>>name;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cout<<"请选择该职工的岗位编号(1-3):";
cin>>d_id;
while(1) //确保输入正确
{
if(d_id == 1||d_id == 2||d_id == 3)
break;
else
{
cout<<"职工岗位编号输入有误,请重新输入(1-3):";
cin>>d_id;
}
}
//保存输入员工的信息
Worker *w = NULL;
switch(d_id)
{
case 1:
w = new Employee(w_id,name,d_id);
break;
case 2:
w = new Manager(w_id,name,d_id);
break;
case 3:
w = new Boss(w_id,name,d_id);
break;
default:
break;
}
//将新添加的职工指针保存到数组指针中
newspace[this->Num+i] = w;
}
delete []this->w_arr; //释放原有数组
this->w_arr = newspace; //更新新空间的指向
this->Num = newsize; //更新人数
this->save_to_file(); //保存数据到文件中
this->fileIsEmpty = false; //文件不为空
cout<<"成功添加"<<add_num<<"名职工的信息!"<<endl;
}
else
{
cout<<"输入有误!"<<endl;
}
//按任意键返回上级并清屏
system("pause");
system("cls");
}
程序运行结果如下图所示。
五、读写文件操作
每次重新运行程序的时候,数组中存放的内容都是空的,上一次运行后的数据在程序结束时会被删除,这不太符合实际,应当将每次运行程序后添加的数据写入到文件中,这样在程序再次运行时,数据也是存在的。
将新添加的职工数据写入到文件中的函数实现如下。
void WorkerManager::save_to_file() //将数据保存到文件的函数实现
{
ofstream ofs;
ofs.open(FILENAME,ios::out); //往文件中写数据
//将所有员工的数据写入到文件中
//ofs <<"职工编号\t"<<"职工姓名\t"<<"职工部门"<<endl;
for(int i=0;i<this->Num;i++)
{
ofs << w_arr[i]->worker_id<<"\t"
<< w_arr[i]->name<<"\t"
<< w_arr[i]->dep_id<<endl;
}
ofs.close();
}
可以看到,用户输入的各项信息成功的写入到了文件中。
还有读文件的操作,文件的状态在本案例中应当有三种。第一种是文件不存在,在第一次添加员工后,文件才会创建;第二种是文件存在,但是里面的内容为空,就是添加员工信息之后又删除了;第三种是文件存在且里面的内容不为空,这种情况就比较复杂,需要将文件中记录的员工数量进行统计,然后再对相关属性进行初始化。
WorkerManager.cpp文件中的相关函数如下。
int WorkerManager::getEmpNum() //统计文件中的职工个数的函数实现
{
ifstream ifs;
ifs.open(FILENAME,ios::in); //读文件
int w_id;
string name;
int d_id;
int num=0;
while(ifs>>w_id && ifs>>name && ifs>>d_id)
{
num++;
}
return num;
}
void WorkerManager::initEmp() //初始化员工的函数实现
{
ifstream ifs;
ifs.open(FILENAME,ios::in);
int w_id;
string name;
int d_id;
int index=0;
while(ifs>>w_id && ifs>>name && ifs>>d_id)
{
Worker *w = NULL;
if(d_id==1)
{
w = new Employee(w_id,name,d_id); //普通员工
}
else if(d_id==2)
{
w = new Manager(w_id,name,d_id); //经理
}
else
{
w = new Boss(w_id,name,d_id); //老板
}
this->w_arr[index] = w; //存放到数组中
index++;
}
ifs.close();
}
构造函数中对应三种情况的初始化代码如下。
WorkerManager::WorkerManager()
{
ifstream ifs;
ifs.open(FILENAME,ios::in); //读文件
//1.文件不存在
if(!ifs.is_open())
{
//初始化属性
this->Num = 0;
this->w_arr = NULL;
this->fileIsEmpty = true;
ifs.close();
return; //返回,不进行后续操作
}
//2.文件存在且内容为空
char ch;
ifs >> ch; //读一个字符
if(ifs.eof())
{
//初始化属性
this->Num = 0;
this->w_arr = NULL;
this->fileIsEmpty = true;
ifs.close();
return; //返回,不进行后续操作
}
//3.文件存在且内容不为空
this->fileIsEmpty = false;
int num = this->getEmpNum(); //获取文件中已有的职工数量
//初始化属性
this->Num = num;
this->w_arr = new Worker*[this->Num]; //在堆区开辟数组
this->initEmp(); //将文件中的数据保存到数组
}
六、显示职工信息
显示职工信息比较简单,首先判断文件是否存在,如果不存在就打印提示信息,如果存在就将所有的职工信息进行输出。
void WorkerManager::display_employee() //显示职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,没有可显示的内容!"<<endl;
}
else
{
for(int i=0;i<this->Num;i++)
{
this->w_arr[i]->show_info(); //显示职工信息
}
}
//按任意键后清屏
system("pause");
system("cls");
}
程序运行的结果如下图所示。
如果将文件删除,再次运行程序,结果如下图所示。
七、删除职工信息
删除职工信息需要注意将职工的数量和数组指针做同步的更新,并将信息在文件中也做同步更新。
在删除职工信息之前需要先判断该职工信息是否存在,删除职工信息的函数实现如下。
int WorkerManager::isExist(int id) //判断职工是否存在的函数实现
{
for(int i=0;i<this->Num;i++)
{
if(this->w_arr[i]->worker_id == id)
return i;
}
return -1;
}
void WorkerManager::delete_employee() //删除职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行删除操作!"<<endl;
}
else
{
int w_id,ret;
cout<<"请输入要删除的职工编号:";
cin>>w_id;
ret = this->isExist(w_id);
if(ret != -1)
{
for(int i=ret;i<this->Num-1;i++)
{
this->w_arr[i] = this->w_arr[i+1];
}
this->Num--; //更新数组中存放的元素个数
this->save_to_file(); //数据同步更新到文件中
cout<<"已删除职工编号为"<<w_id<<"的职工信息!"<<endl;
}
else
{
cout<<"职工编号为"<<w_id<<"的职工不存在,删除失败!"<<endl;
}
}
//按任意键后清屏
system("pause");
system("cls");
}
先显示一下现有的职工信息,如下图所示。
然后删除掉其中的一个职工的信息,如下图所示,提示删除成功。
再次显示职工信息,如下图所示,删除确实成功了。
再打开对应的文件查看内容,如下图所示,信息是同步的,文件中的数据也被删除掉了。
如果输入一个不存在的职工编号,会出现如下图所示的提示信息。
八、修改职工信息
修改职工信息时,再查找到对应的职工编号后,删除原有记录,然后根据用户输入在该位置添加新的职工信息。
修改职工信息的函数实现代码如下。
void WorkerManager::modify_employee() //修改职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行修改操作!"<<endl;
}
else
{
int w_id,ret;
cout<<"请输入要修改的职工编号:";
cin>>w_id;
ret = this->isExist(w_id);
if(ret != -1)
{
delete this->w_arr[ret];
int new_id;
string new_name;
int new_d_id;
cout<<"职工编号为"<<w_id<<"的职工信息存在,请输入新的职工编号:";
cin>>new_id;
cout<<"请输入新的职工姓名:";
cin>>new_name;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cout<<"请选择该职工的岗位编号(1-3):";
cin>>new_d_id;
while(1) //确保输入正确
{
if(new_d_id == 1||new_d_id == 2||new_d_id == 3)
break;
else
{
cout<<"职工岗位编号输入有误,请重新输入(1-3):";
cin>>new_d_id;
}
}
//保存输入员工的信息
Worker *w = NULL;
switch(new_d_id)
{
case 1:
w = new Employee(new_id,new_name,new_d_id);
break;
case 2:
w = new Manager(new_id,new_name,new_d_id);
break;
case 3:
w = new Boss(new_id,new_name,new_d_id);
break;
default:
break;
}
//将修改的职工指针保存到数组指针中
this->w_arr[ret] = w;
this->save_to_file(); //数据同步更新到文件中
cout<<"职工编号为"<<w_id<<"的职工信息修改成功!"<<endl;
}
else
{
cout<<"职工编号为"<<w_id<<"的职工不存在!"<<endl;
}
}
//按任意键后清屏
system("pause");
system("cls");
}
程序运行后同样先显示职工信息,如下图所示。
然后修改职工信息,修改过程如下图所示。
修改完成后再显示职工信息如下图所示。
修改完成后,再输入旧的职工编号进行修改,提示该职工不存在。
修改完成后,打开文件如下图所示,信息都同步更新了!
九、查找职工信息
查找职工信息可以按照职工编号查询,也可以按照职工姓名进行查询。
查找职工信息的函数实现代码如下。
void WorkerManager::find_employee() //查找职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行查找操作!"<<endl;
}
else
{
cout<<"1.按职工编号查"<<endl;
cout<<"2.按职工姓名查"<<endl;
cout<<"请选择要查找的方式(1-2):";
int select;
cin>>select;
while(1) //确保输入正确
{
if(select == 1||select == 2)
break;
else
{
cout<<"输入有误,请重新选择要查找的方式(1-2):";
cin>>select;
}
}
if(select==1) //按职工编号查
{
cout<<"请输入要查找的职工编号:";
int id;
cin>>id;
if(isExist(id)!=-1)
{
cout<<"查找成功,该职工的信息如下:"<<endl;
this->w_arr[isExist(id)]->show_info();
}
else
{
cout<<"职工编号为"<<id<<"的职工信息不存在!"<<endl;
}
}
else //按职工姓名查
{
cout<<"请输入要查找的职工姓名:";
bool flag=false;
string name;
cin>>name;
for(int i=0;i<this->Num;i++)
{
if(name==this->w_arr[i]->name)
{
if(!flag)
{
cout<<"查找成功,职工的信息如下:"<<endl;
}
this->w_arr[i]->show_info();
flag=true;
}
}
if(!flag)
{
cout<<"职工姓名为"<<name<<"的职工信息不存在!"<<endl;
}
}
}
//按任意键后清屏
system("pause");
system("cls");
}
程序运行后还是先显示一下职工信息,如下图所示。
按照职工编号查询的过程如下图所示。
按照职工姓名查询的过程如下图所示,按照职工姓名查询时可能会遇到重名的职工,要将所有同名的职工信息都进行打印。
按照职工编号查询不存在的情况如下图所示。
按照职工姓名查询不存在的情况如下图所示。
十、对职工信息排序
对职工信息排序时按照职工编号进行排序,具体是升序还是降序由用户选择。
对职工信息排序的函数代码实现如下。
void WorkerManager::sort_employee() //对职工信息排序的函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行排序操作!"<<endl;
//按任意键后清屏
system("pause");
system("cls");
}
else
{
cout<<"1.按照职工编号升序排列"<<endl;
cout<<"2.按照职工编号降序排列"<<endl;
cout<<"请选择要排序的方式(1-2):";
int select;
cin>>select;
while(1) //确保输入正确
{
if(select == 1||select == 2)
break;
else
{
cout<<"输入有误,请重新选择要排序的方式(1-2):";
cin>>select;
}
}
for(int i=0;i<this->Num;i++)
{
int m=i;
for(int j=i+1;j<this->Num;j++)
{
if(select == 1) //按照职工编号升序排列
{
if(this->w_arr[j]->worker_id < this->w_arr[m]->worker_id)
{
m = j;
}
}
else //按照职工编号降序排列
{
if(this->w_arr[j]->worker_id > this->w_arr[m]->worker_id)
{
m = j;
}
}
}
if(m != i) //m的值有变化就交换
{
Worker *temp = w_arr[i];
w_arr[i] = w_arr[m];
w_arr[m] = temp;
}
}
this->save_to_file(); //将信息同步到文件中
cout<<"排序成功!排序后的结果如下:"<<endl;
this->display_employee(); //该函数中有按任意键后清屏操作
}
}
程序运行后先显示一下职工信息,如下图所示,是无序的。
选择按职工编号升序排列的执行过程如下图所示。
选择按职工编号降序排列的执行过程如下图所示。
文件中的信息如下图所示,也是同步变化的。
十一、清空文件内容
清空文件内容需要在文件打开方式中将其设置为 ios::trunc,如果文件存在就先删除,再创建。然后需要操作的就是将数组中的数据清空,同时将职工总数量设置为0。
清空文件内容函数的代码如下。
void WorkerManager::clear_file() //清空文件的函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或已经为空!"<<endl;
}
else
{
cout<<"1.确定"<<endl;
cout<<"2.取消"<<endl;
cout<<"确定清空文件数据?";
int select;
cin>>select;
if(select==1)
{
ofstream ofs;
ofs.open(FILENAME,ios::trunc); //文件存在就删除文件,并重新创建
ofs.close();
//释放堆区内存
if(this->w_arr != NULL)
{
for(int i=0;i<this->Num;i++) //将每个元素都置空
{
delete this->w_arr[i];
this->w_arr[i] = NULL;
}
delete []this->w_arr; //删除并置空堆区数组指针
this->w_arr = NULL;
}
//初始化属性
this->Num = 0;
this->fileIsEmpty = true;
cout<<"文件清空成功!"<<endl;
}
}
//按任意键后清屏
system("pause");
system("cls");
}
程序运行后先显示职工信息,如下图所示。
清空后打开文件如下图所示,文件内容也被清空了。
文件被清空后,只能选择菜单0退出程序或菜单1增加职工信息,其它操作均不能进行。
文件被清空后执行显示操作如下图所示。
文件被清空后执行删除操作如下图所示。
文件被清空后执行修改操作如下图所示。
文件被清空后执行查找操作如下图所示。
文件被清空后执行排序操作如下图所示。
文件被清空后执行清空文件的操作如下图所示。
十二、工程文件构成
本案例的工程主要包含以下四个文件。
worker.h文件的内容如下。
#pragma once //防止头文件重复包含
#include <iostream>
#include <string>
using namespace std;
class Worker
{
public:
//成员方法
virtual void show_info() = 0; //显示员工信息的纯虚函数
virtual string get_dep() = 0; //获取员工部门的纯虚函数
//成员属性
int worker_id; //员工编号
string name; //员工姓名
int dep_id; //员工部门编号
};
class Employee : public Worker //普通职工类
{
public:
Employee(int worker_id,string name,int dep_id)
{
this->worker_id = worker_id;
this->name = name;
this->dep_id = dep_id;
}
void show_info() //显示员工信息的函数实现
{
cout<<"职工编号:"<<worker_id<<"\t职工姓名:"<<name<<"\t职工岗位:"<<get_dep()<<endl;
}
string get_dep() //获取员工部门的函数实现
{
return "普通员工";
}
};
class Manager : public Worker //经理类
{
public:
Manager(int worker_id,string name,int dep_id)
{
this->worker_id = worker_id;
this->name = name;
this->dep_id = dep_id;
}
void show_info() //显示员工信息的函数实现
{
cout<<"职工编号:"<<worker_id<<"\t职工姓名:"<<name<<"\t职工岗位:"<<get_dep()<<endl;
}
string get_dep() //获取员工部门的函数实现
{
return "经理";
}
};
class Boss : public Worker //老板类
{
public:
Boss(int worker_id,string name,int dep_id)
{
this->worker_id = worker_id;
this->name = name;
this->dep_id = dep_id;
}
void show_info() //显示员工信息的函数实现
{
cout<<"职工编号:"<<worker_id<<"\t职工姓名:"<<name<<"\t职工岗位:"<<get_dep()<<endl;
}
string get_dep() //获取员工部门的函数实现
{
return "老板";
}
};
workerManager.h文件的内容如下。
#pragma once //防止头文件重复包含
#include <iostream>
#include <fstream> //文件操作的头文件
using namespace std;
#include "worker.h"
#define FILENAME "Employee.txt" //宏定义文件名称
class WorkerManager
{
public:
WorkerManager(); //构造函数
void show_menu(); //显示菜单函数的声明
void exit_system(); //退出系统函数的声明
int Num; //总人数
Worker **w_arr; //存放职工的数组指针
void add_employee(); //添加职工信息函数声明
void save_to_file(); //将数据保存到文件的函数声明
bool fileIsEmpty; //文件是否为空的标志
int getEmpNum(); //统计文件中的职工个数的函数声明
void initEmp(); //初始化员工的函数声明
void display_employee(); //显示职工信息函数声明
int isExist(int id); //判断职工是否存在的函数声明
void delete_employee(); //删除职工信息函数声明
void modify_employee(); //修改职工信息函数声明
void find_employee(); //查找职工信息函数声明
void sort_employee(); //对职工信息排序的函数声明
void clear_file(); //清空文件的函数声明
~WorkerManager(); //析构函数
};
main.cpp文件的内容如下。
#include <iostream>
#include <string>
using namespace std;
#include "workerManager.h"
#include "worker.h"
int main()
{
WorkerManager wm; //实例化一个对象
int menu_choice = 0; //用户菜单选择
while(1)
{
wm.show_menu(); //调用成员函数显示菜单
cout<<"请输入您要操作的菜单编号:";
cin>>menu_choice;
switch(menu_choice)
{
case 0: //退出管理程序
wm.exit_system();
break;
case 1: //增加职工信息
wm.add_employee();
break;
case 2: //显示职工信息
wm.display_employee();
break;
case 3: //删除职工信息
wm.delete_employee();
break;
case 4: //修改职工信息
wm.modify_employee();
break;
case 5: //查找职工信息
wm.find_employee();
break;
case 6: //按照选择排序
wm.sort_employee();
break;
case 7: //清空所有信息
wm.clear_file();
break;
default:
system("cls"); //清屏操作
break;
}
}
system("pause");
return 0;
}
WorkerManager.cpp文件中的内容如下。
#include "workerManager.h"
WorkerManager::WorkerManager()
{
ifstream ifs;
ifs.open(FILENAME,ios::in); //读文件
//1.文件不存在
if(!ifs.is_open())
{
//初始化属性
this->Num = 0;
this->w_arr = NULL;
this->fileIsEmpty = true;
ifs.close();
return; //返回,不进行后续操作
}
//2.文件存在且内容为空
char ch;
ifs >> ch; //读一个字符
if(ifs.eof())
{
//初始化属性
this->Num = 0;
this->w_arr = NULL;
this->fileIsEmpty = true;
ifs.close();
return; //返回,不进行后续操作
}
//3.文件存在且内容不为空
this->fileIsEmpty = false;
int num = this->getEmpNum(); //获取文件中已有的职工数量
//初始化属性
this->Num = num;
this->w_arr = new Worker*[this->Num]; //在堆区开辟数组
this->initEmp(); //将文件中的数据保存到数组
}
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::exit_system() //退出系统函数的实现
{
cout<<"欢迎下次继续使用!"<<endl;
system("pause"); //按任意键继续
exit(0); //退出程序
}
void WorkerManager::add_employee() //添加职工信息函数的实现
{
cout<<"请输入要添加职工的数量:";
int add_num=0;
cin>>add_num;
if(add_num > 0)
{
int newsize = this->Num + add_num; //新空间的数组大小
Worker **newspace = new Worker*[newsize]; //开辟新空间
//如果原来的数组不为空就进行拷贝
if(this->w_arr != NULL)
{
for(int i=0;i<this->Num;i++)
{
newspace[i] = this->w_arr[i]; //将原数组中的数据拷贝到扩展后的新数组中
}
}
//批量添加职工信息
for(int i=0;i<add_num;i++)
{
int w_id;
string name;
int d_id;
cout<<"请输入第"<<i+1<<"个职工的职工编号:";
cin>>w_id;
while(1) //根据职工编号判断职工信息是否已经存在
{
int j;
for(j=0;j<this->Num+i;j++)
{
if(w_id == newspace[j]->worker_id)
{
break;
}
}
if(j==this->Num+i) //没有重复的职工编号
{
break;
}
else
{
cout<<"编号为"<<w_id<<"的职工信息已存在!"<<endl;
cout<<"请重新输入第"<<i+1<<"个职工的职工编号:";
cin>>w_id;
}
}
cout<<"请输入第"<<i+1<<"个职工的职工姓名:";
cin>>name;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cout<<"请选择该职工的岗位编号(1-3):";
cin>>d_id;
while(1) //确保输入正确
{
if(d_id == 1||d_id == 2||d_id == 3)
break;
else
{
cout<<"职工岗位编号输入有误,请重新输入(1-3):";
cin>>d_id;
}
}
//保存输入员工的信息
Worker *w = NULL;
switch(d_id)
{
case 1:
w = new Employee(w_id,name,d_id);
break;
case 2:
w = new Manager(w_id,name,d_id);
break;
case 3:
w = new Boss(w_id,name,d_id);
break;
default:
break;
}
//将新添加的职工指针保存到数组指针中
newspace[this->Num+i] = w;
}
delete []this->w_arr; //释放原有数组
this->w_arr = newspace; //更新新空间的指向
this->Num = newsize; //更新人数
this->save_to_file(); //保存数据到文件中
this->fileIsEmpty = false; //文件不为空
cout<<"成功添加"<<add_num<<"名职工的信息!"<<endl;
}
else
{
cout<<"输入有误!"<<endl;
}
//按任意键返回上级并清屏
system("pause");
system("cls");
}
void WorkerManager::save_to_file() //将数据保存到文件的函数实现
{
ofstream ofs;
ofs.open(FILENAME,ios::out); //往文件中写数据
//将所有员工的数据写入到文件中
//ofs <<"职工编号\t"<<"职工姓名\t"<<"职工部门"<<endl;
for(int i=0;i<this->Num;i++)
{
ofs << w_arr[i]->worker_id<<"\t"
<< w_arr[i]->name<<"\t"
<< w_arr[i]->dep_id<<endl;
}
ofs.close();
}
int WorkerManager::getEmpNum() //统计文件中的职工个数的函数实现
{
ifstream ifs;
ifs.open(FILENAME,ios::in); //读文件
int w_id;
string name;
int d_id;
int num=0;
while(ifs>>w_id && ifs>>name && ifs>>d_id)
{
num++;
}
return num;
}
void WorkerManager::initEmp() //初始化员工的函数实现
{
ifstream ifs;
ifs.open(FILENAME,ios::in);
int w_id;
string name;
int d_id;
int index=0;
while(ifs>>w_id && ifs>>name && ifs>>d_id)
{
Worker *w = NULL;
if(d_id==1)
{
w = new Employee(w_id,name,d_id); //普通员工
}
else if(d_id==2)
{
w = new Manager(w_id,name,d_id); //经理
}
else
{
w = new Boss(w_id,name,d_id); //老板
}
this->w_arr[index] = w; //存放到数组中
index++;
}
ifs.close();
}
void WorkerManager::display_employee() //显示职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,没有可显示的内容!"<<endl;
}
else
{
for(int i=0;i<this->Num;i++)
{
this->w_arr[i]->show_info(); //显示职工信息
}
}
//按任意键后清屏
system("pause");
system("cls");
}
int WorkerManager::isExist(int id) //判断职工是否存在的函数实现
{
for(int i=0;i<this->Num;i++)
{
if(this->w_arr[i]->worker_id == id)
return i;
}
return -1;
}
void WorkerManager::delete_employee() //删除职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行删除操作!"<<endl;
}
else
{
int w_id,ret;
cout<<"请输入要删除的职工编号:";
cin>>w_id;
ret = this->isExist(w_id);
if(ret != -1)
{
for(int i=ret;i<this->Num-1;i++)
{
this->w_arr[i] = this->w_arr[i+1];
}
this->Num--; //更新数组中存放的元素个数
this->save_to_file(); //数据同步更新到文件中
cout<<"已删除职工编号为"<<w_id<<"的职工信息!"<<endl;
}
else
{
cout<<"职工编号为"<<w_id<<"的职工不存在,删除失败!"<<endl;
}
}
//按任意键后清屏
system("pause");
system("cls");
}
void WorkerManager::modify_employee() //修改职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行修改操作!"<<endl;
}
else
{
int w_id,ret;
cout<<"请输入要修改的职工编号:";
cin>>w_id;
ret = this->isExist(w_id);
if(ret != -1)
{
delete this->w_arr[ret];
int new_id;
string new_name;
int new_d_id;
cout<<"职工编号为"<<w_id<<"的职工信息存在,请输入新的职工编号:";
cin>>new_id;
cout<<"请输入新的职工姓名:";
cin>>new_name;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cout<<"请选择该职工的岗位编号(1-3):";
cin>>new_d_id;
while(1) //确保输入正确
{
if(new_d_id == 1||new_d_id == 2||new_d_id == 3)
break;
else
{
cout<<"职工岗位编号输入有误,请重新输入(1-3):";
cin>>new_d_id;
}
}
//保存输入员工的信息
Worker *w = NULL;
switch(new_d_id)
{
case 1:
w = new Employee(new_id,new_name,new_d_id);
break;
case 2:
w = new Manager(new_id,new_name,new_d_id);
break;
case 3:
w = new Boss(new_id,new_name,new_d_id);
break;
default:
break;
}
//将修改的职工指针保存到数组指针中
this->w_arr[ret] = w;
this->save_to_file(); //数据同步更新到文件中
cout<<"职工编号为"<<w_id<<"的职工信息修改成功!"<<endl;
}
else
{
cout<<"职工编号为"<<w_id<<"的职工不存在!"<<endl;
}
}
//按任意键后清屏
system("pause");
system("cls");
}
void WorkerManager::find_employee() //查找职工信息函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行查找操作!"<<endl;
}
else
{
cout<<"1.按职工编号查"<<endl;
cout<<"2.按职工姓名查"<<endl;
cout<<"请选择要查找的方式(1-2):";
int select;
cin>>select;
while(1) //确保输入正确
{
if(select == 1||select == 2)
break;
else
{
cout<<"输入有误,请重新选择要查找的方式(1-2):";
cin>>select;
}
}
if(select==1) //按职工编号查
{
cout<<"请输入要查找的职工编号:";
int id;
cin>>id;
if(isExist(id)!=-1)
{
cout<<"查找成功,该职工的信息如下:"<<endl;
this->w_arr[isExist(id)]->show_info();
}
else
{
cout<<"职工编号为"<<id<<"的职工信息不存在!"<<endl;
}
}
else //按职工姓名查
{
cout<<"请输入要查找的职工姓名:";
bool flag=false;
string name;
cin>>name;
for(int i=0;i<this->Num;i++)
{
if(name==this->w_arr[i]->name)
{
if(!flag)
{
cout<<"查找成功,职工的信息如下:"<<endl;
}
this->w_arr[i]->show_info();
flag=true;
}
}
if(!flag)
{
cout<<"职工姓名为"<<name<<"的职工信息不存在!"<<endl;
}
}
}
//按任意键后清屏
system("pause");
system("cls");
}
void WorkerManager::sort_employee() //对职工信息排序的函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或记录为空,无法进行排序操作!"<<endl;
//按任意键后清屏
system("pause");
system("cls");
}
else
{
cout<<"1.按照职工编号升序排列"<<endl;
cout<<"2.按照职工编号降序排列"<<endl;
cout<<"请选择要排序的方式(1-2):";
int select;
cin>>select;
while(1) //确保输入正确
{
if(select == 1||select == 2)
break;
else
{
cout<<"输入有误,请重新选择要排序的方式(1-2):";
cin>>select;
}
}
for(int i=0;i<this->Num;i++)
{
int m=i;
for(int j=i+1;j<this->Num;j++)
{
if(select == 1) //按照职工编号升序排列
{
if(this->w_arr[j]->worker_id < this->w_arr[m]->worker_id)
{
m = j;
}
}
else //按照职工编号降序排列
{
if(this->w_arr[j]->worker_id > this->w_arr[m]->worker_id)
{
m = j;
}
}
}
if(m != i) //m的值有变化就交换
{
Worker *temp = w_arr[i];
w_arr[i] = w_arr[m];
w_arr[m] = temp;
}
}
this->save_to_file(); //将信息同步到文件中
cout<<"排序成功!排序后的结果如下:"<<endl;
this->display_employee(); //该函数中有按任意键后清屏操作
}
}
void WorkerManager::clear_file() //清空文件的函数实现
{
if(this->fileIsEmpty)
{
cout<<"文件不存在或已经为空!"<<endl;
}
else
{
cout<<"1.确定"<<endl;
cout<<"2.取消"<<endl;
cout<<"确定清空文件数据?";
int select;
cin>>select;
if(select==1)
{
ofstream ofs;
ofs.open(FILENAME,ios::trunc); //文件存在就删除文件,并重新创建
ofs.close();
//释放堆区内存
if(this->w_arr != NULL)
{
for(int i=0;i<this->Num;i++) //将每个元素都置空
{
delete this->w_arr[i];
this->w_arr[i] = NULL;
}
delete []this->w_arr; //删除并置空堆区数组指针
this->w_arr = NULL;
}
//初始化属性
this->Num = 0;
this->fileIsEmpty = true;
cout<<"文件清空成功!"<<endl;
}
}
//按任意键后清屏
system("pause");
system("cls");
}
WorkerManager::~WorkerManager()
{
//释放堆区内存
if(this->w_arr != NULL)
{
for(int i=0;i<this->Num;i++) //将每个元素都置空
{
delete this->w_arr[i];
this->w_arr[i] = NULL;
}
delete []this->w_arr; //删除并置空堆区数组指针
this->w_arr = NULL;
}
}
本文的项目工程文件:点此下载
本文参考视频:
黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难