一个职工管理系统的案例
头文件
//职工
#pragma once
#include<iostream>
using namespace std;
class Worker
{
public:
//行为
virtual void ShowInfo() = 0;
virtual string getDpetName() = 0;
//属性
int m_Id;
string m_Name;
int m_DeptId;
};
//职工——老板
#pragma once
#include<iostream>
using namespace std;
#include "worker.h"
class Boss :public Worker
{
public:
Boss(int id, string name, int dId);
virtual void ShowInfol();
virtual string getDptname();
};
//职工——员工
#pragma once
#include<iostream>
using namespace std;
#include "worker.h"
class Employee:public Worker
{
public:
Employee(int id,string name,int dId);
void ShowInfol();
string getDptname();
};
//职工——经理
#pragma once
#include<iostream>
using namespace std;
#include "worker.h"
class Manager :public Worker
{
public:
Manager(int id, string name, int dId);
virtual void ShowInfol();
virtual string getDptname();
};
多态调用职工,这一部分基本没问题
//接口函数Manager
#pragma once
#include<iostream>
using namespace std;
#include"worker.h"
#include"boss.h"
#include"employee.h"
#include"manager.h"
#include<fstream>
#define FILENAME "filename.txt"//****引号
class WorkerManager
{
public:
//构造函数
WorkerManager();
//菜单显示
void ShowMenu();
//0、退出系统
void Exit();
//1、添加职工
void AddEmp();
//保存职工到文件中
void save();
//获取职工数量
int getNum();
//初始化职工
void initEmp();
//2、显示职工
void ShowEmp();
//3、删除职工
void DelEmp();
//职工存在函数
int ExitEmp(int id);
//4、修改职工
void ModEmp();
//5、查找职工
void FindEmp();
//6、职工排序
void SortEmp();
//7、清空文件
void Clear();
//析构函数
~WorkerManager();
//属性
int m_empNum;//职工的数量
Worker** m_empArr;//存放职工的数组
bool Isempty;
};
基本思路以及各个模块的功能函数能理清
首先构造函数实现初始化,因为初始化的本意就是将文件夹里的职工文件读到内存系统中来,这样才能方便对职工进行后续的操作,所以初始化说白了也就是实现文件读入的功能 ,这细分为三种情况:
1、文件夹里不存在职工文件
2、文件夹里存在职工文件但是职工文件里数据为空,还没开始写职工
3、文件夹里有已经实现好的职工文件
根据上述三个不同的情况进行初始化——初始化1,采用读入文件时的一个函数ifs.is_open(),判断如果读不到,直接文件不存在;初始化2,亦采用一个ifs.eof()函数,先自己准备一个字符读取一下,然后判断是否end of;初始化3,这个时候已经存在职工文件了,所以需要的就是将文件读到内存中来,所以首先需要在内存中声明一个存放职工的数组,即先开辟一个空间,开辟空间需要知道空间的大小,即文件中职工的个数,所以需要一个getNum()函数先确定职工人数,其次将开辟的空间内填满职工,所以需要一个initEmp()函数,进行初始化,说白了就是实行一个空间填充的工作;
职工读入系统完成,进行后续操作,提供一个ShowMenu()菜单让用户选择功能:
添加职工AddEmp(),基本思路,确定添加个数,开辟空间,判断内存中是否存在原职工,如果存在则将原空间的职工放到新空间中来,批量添加,更新空间,文件保存save()函数
批量添加时的数组溢出情况,解决不了
显示职工ShowEmp(),根据数量循环显示即可
删除职工DelEmp(),以编号删除为思路,根据编号查到要删除的人,所以想需要一个Exit()函数确定所搜编号是否存在,删除实现一个简单的前移覆盖
查找职工FindEmp(),两种方式,不同之处在于,按编号查找由于Exit()函数的存在并根据该函数的返回值就可直接显示结果,但是按姓名查找以此为思路并不好直接显示是否查找到,因为再一次循环中查找到的话是可以直接显示的,但是如果没找到就不好直接显示,所以需要确定一个标志位来解决这个问题
修改职工ModEmp(),先查找,再修改,改完更新保存
职工排序SortEmp(),选择排序
清空文件Clear(),清空指针数组,先每个清空,最后整体置空
析构函数,清空系统空间内的职工数据
源文件
//老板
#include<iostream>
using namespace std;
#include "boss.h"
Boss::Boss(int id, string name, int dId)
{
m_Id = id;
m_name = name;
m_DptId = dId;
}
void Boss::ShowInfol()
{
cout << "职工编号:" << m_Id << " "
<< "职工姓名:" << m_name << " "
<< "职工岗位:" << getDptname() << endl;
}
string Boss::getDptname()
{
return string("老板");
}
//员工
#include<iostream>
using namespace std;
#include "Employee.h"
Employee::Employee(int id, string name, int dId)
{
m_Id = id;
m_name = name;
m_DptId = dId;
}
void Employee::ShowInfol()
{
cout << "职工编号:" << m_Id << " "
<< "职工姓名:" << m_name << " "
<< "职工岗位:" << getDptname() << endl;
}
string Employee::getDptname()
{
return string("员工");
}
//经理
#include<iostream>
using namespace std;
#include "Manager.h"
Manager::Manager(int id, string name, int dId)
{
m_Id = id;
m_name = name;
m_DptId = dId;
}
void Manager::ShowInfol()
{
cout << "职工编号:" << m_Id << " "
<< "职工姓名:" << m_name << " "
<< "职工岗位:" << getDptname() << endl;
}
string Manager::getDptname()
{
return string("经理");
}
//接口函数
#include"workermanager.h"
//此处不添加输入输出流以及namespace
//构造函数
WorkerManager::WorkerManager()
{
//系统初始化
//——1、文件不存在
ifstream ifs;
ifs.open(FILENAME, ios::in);
if (!ifs.is_open())
{
cout << "文件不存在!" << endl;
m_empNum = 0;
m_empArr = NULL;
Isempty = true;
}
//——2、文件存在但是数据为空
//定义一个字符,读此文件如果读完该字符直接结束说明数据为空
char ch;
ifs >> ch;
if (ifs.eof())
{
cout << "文件存在但数据为空!" << endl;
m_empNum = 0;
m_empArr = NULL;
Isempty = true;
}
//——3、文件存在
//————但文件存在时,首先要知道总共有几名职工
//————根据职工的数量进行初始化操作
//————需要一个获取职工数量函数以及一个职工初始化函数
int num = getNum();
m_empNum = num;
Isempty = false;
//****开辟空间
m_empArr = new Worker * [m_empNum];
//存入数组
initEmp();
}
//菜单显示
void WorkerManager::ShowMenu()
{
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;
}
//0、退出系统
void WorkerManager::Exit()
{
cout << "欢迎下次使用!" << endl;
system("pause");
exit(0);//退出系统
}
//1、添加职工
void WorkerManager::AddEmp()
{
cout << "请输入添加的个数:" << endl;
int addnum;
cin >> addnum;
if (addnum > 0)
{
//添加
//计算总人数
int newsize = m_empNum + addnum;
//根据人数创建空间
Worker** newspace = new Worker * [newsize];
//原有职工数的移植,移植到新空间下
if (m_empArr != NULL)
{
for (int i = 0; i < m_empNum; i++)
{
newspace[i] = m_empArr[i];
}
}
//批量添加新职工
for (int i = 0; i < addnum; i++)
{
int id;
cout << "输入添加第" << i + 1 << "名新职工的编号:" << endl;
cin >> id;
string name;
cout << "输入添加第" << i + 1 << "名新职工的姓名:" << endl;
cin >> name;
cout << "选择添加职工的岗位:" << endl;
cout << "1、员工" << endl;
cout << "2、经理" << endl;
cout << "3、老板" << endl;
int select;
cin >> select;
Worker* worker = NULL;
switch (select)
{
case 1:
worker = new Employee(id, name, select);
break;
case 2:
worker = new Manager(id, name, select);
break;
case 3:
worker = new Boss(id, name, select);
break;
default:
break;
}
newspace[m_empNum + i] = worker;
}
//删除原空间
delete[] m_empArr;
//将创建的职工加入空间内
//更新空间
m_empArr = newspace;
//更新人数
m_empNum = newsize;
//保存
save();
//添加成功
cout << "成功添加" << addnum << "名职工!" << endl;
}
else
{
cout << "输入有误!" << endl;
}
system("pause");
system("cls");
}
//保存职工到文件中
void WorkerManager::save()
{
ofstream ofs;
ofs.open(FILENAME, ios::out);
for (int i = 0; i < m_empNum; i++)
{
ofs << m_empArr[i]->m_Id << " "
<<m_empArr[i]->m_Name << " "
<<m_empArr[i]->m_DeptId << endl;
}
ofs.close();
}
//获取职工数量
int WorkerManager::getNum()
{
ifstream ifs;
//设置三个读入的存入变量
int id;
string name;
int dId;
int num = 0;
if (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, dId);
}
else if (dId == 2)
{
worker = new Manager(id, name, dId);
}
else
{
worker = new Boss(id, name, dId);
}
m_empArr[index] = worker;
index++;
}
ifs.close();
}
//2、显示职工
void WorkerManager::ShowEmp()
{
if (Isempty)
{
cout << "文件将不存在或数据为空!" << endl;
}
else
{
for (int i = 0; i < m_empNum; i++)
{
m_empArr[i]->ShowInfo();
}
}
system("pause");
system("cls");
}
//3、删除职工
void WorkerManager::DelEmp()
{
if (Isempty)
{
cout << "文件不存在或数据为空!" << endl;
}
else
{
cout << "请输入删除的编号:" << endl;
int id;
cin >> id;
int ret = ExitEmp(id);
if (ret != -1)
{
for (int i = ret;i < m_empNum; i++)
{
m_empArr[i] = m_empArr[i + 1];
m_empNum--;
}
save();
cout << "删除成功" << endl;
}
else
{
cout << "查无此人!" << endl;
}
}
system("pause");
system("cls");
}
//职工存在函数
int WorkerManager::ExitEmp(int id)
{
int index = -1;
for (int i = 0; i < m_empNum;i++)
{
if (m_empArr[i]->m_Id == id)
{
index = i;
}
}
return index;
}
//4、修改职工
void WorkerManager::ModEmp()
{
if (Isempty)
{
cout << "文件不存在或数据为空!" << endl;
}
else
{
cout << "请输入要修改的编号:" << endl;
int id;
cin >> id;
int ret = ExitEmp(id);
if (ret != -1)
{
cout << "需要修改的职工信息:" << endl;
m_empArr[ret]->ShowInfo();
int newid;
string newname;
int newselect;
cout << "输入修改编号:" << endl;
cin >> newid;
cout << "输入修改姓名:" << endl;
cin >> newname;
cout << "选择修改岗位:" << endl;
cout << "1、员工" << endl;
cout << "2、经理" << endl;
cout << "3、老板" << endl;
cin >> newselect;
Worker* worker = NULL;
switch (newselect)
{
case 1:
worker = new Employee(newid, newname, newselect);
break;
case 2:
worker = new Manager(newid, newname, newselect);
break;
case 3:
worker = new Boss(newid, newname, newselect);
break;
}
m_empArr[ret] = worker;
save();
cout << "修改成功!" << endl;
}
else
{
cout << "查无此人!" << endl;
}
}
system("pause");
system("cls");
}
//5、查找职工
void WorkerManager::FindEmp()
{
if(Isempty)
{
cout << "文件为空或数据不存在!" << endl;
}
else
{
cout << "请选择查找方式:" << endl;
cout << "1、按编号查找" << endl;
cout << "2、按姓名查找" << endl;
int select;
cin >> select;
if (select == 1)
{
cout << "请输入要查找职工的编号:" << endl;
int id;
cin >> id;
int ret = ExitEmp(id);
if (ret != -1)
{
cout << "查到了,职工信息如下:" << endl;
m_empArr[ret]->ShowInfo();
}
else
{
cout << "查无此人!" << endl;
}
}
else if (select == 2)
{
string name;
cout << "请输入要查找的职工姓名:" << endl;
cin >> name;
bool flags = false;//判断查找到的标志位
for (int i = 0; i < m_empNum; i++)
{
if (m_empArr[i]->m_Name == name)
{
cout << "查到了,职工信息如下:" << endl;
m_empArr[i]->ShowInfo();
flags = true;
}
}
if (flags == false)
{
cout << "查无此人!" << endl;
}
}
}
system("pause");
system("cls");
}
//6、职工排序
void WorkerManager::SortEmp()
{
if (Isempty)
{
cout << "文件不存在或数据为空!" << endl;
}
else
{
cout << "请选择排序方式:" << endl;
cout << "1、按职工编号升序排序" << endl;
cout << "2、按职工编号降序排序" << endl;
int select;
cin >> select;
int minormax;
for (int i = 0; i < m_empNum; i++)
{
minormax = i;
for (int j = i + 1; j < m_empNum; j++)
{
if (select == 1)//升序排序—简单的选择排序功能
{
if (m_empArr[minormax]->m_Id > m_empArr[j]->m_Id)
{
Worker* temp = m_empArr[minormax];
m_empArr[minormax] = m_empArr[j];
m_empArr[j] = temp;
}
}
else//降序排序—简单的选择排序功能
{
if (m_empArr[minormax]->m_Id < m_empArr[j]->m_Id)
{
Worker* temp = m_empArr[minormax];
m_empArr[minormax] = m_empArr[j];
m_empArr[j] = temp;
}
}
}
}
cout << "排序成功!" << endl;
save();
ShowEmp();
}
}
//7、清空文件
void WorkerManager::Clear()
{
if (Isempty)
{
cout << "文件不存在或数据为空!" << endl;
}
else
{
cout << "确定清空文件?" << endl;
cout << "1、确定" << endl;
cout << "2、取消" << endl;
int select;
cin >> select;
if (select == 1)
{
ifstream ofs;
ofs.open(FILENAME, ios::trunc);//trunc打开文件的方式,如果文件存在删除再创建
ofs.close();
if (m_empArr != NULL)
{
for (int i = 0; i < m_empNum; i++)
{
delete m_empArr[i];
}
delete[] m_empArr;
m_empArr = NULL;
m_empNum = 0;
Isempty = true;
}
cout << "清空文件成功!" << endl;
}
else
{
return;
}
}
system("pause");
system("cls");
}
//析构函数
WorkerManager::~WorkerManager()
{
if (m_empArr != NULL)
{
for (int i = 0; i < m_empNum; i++)
{
delete m_empArr[i];
}
delete[] m_empArr;
m_empArr = NULL;
}
}
//主函数
#include<iostream>
using namespace std;
#include"workermanager.h"
#include"employee.h"
#include"boss.h"
#include"manager.h"
//设计一个职工管理系统,实现一些基本的功能
//设计思路,采用多态的技术对不同种类的员工进行设置‘
//采用文件输入输出方式对职工数据进行导入导出
int main()
{
test1
//Worker* worker = NULL;
//worker = new Employee(1, "张三", 2);
//worker->ShowInfo();
//delete worker;
//worker = new Manager(2, "李四", 3);
//worker->ShowInfo();
//delete worker;
//worker = new Boss(3, "王五", 1);
//worker->ShowInfo();
WorkerManager wm;
while (true)
{
wm.ShowMenu();
cout << "请选择系统功能:" << endl;
int select;
cin >> select;
switch (select)
{
case 1:
wm.AddEmp();
break;
case 2:
wm.ShowEmp();
break;
case 3:
wm.DelEmp();
break;
case 4:
wm.ModEmp();
break;
case 5:
wm.FindEmp();
break;
case 6:
wm.SortEmp();
break;
case 7:
wm.Clear();
break;
case 0:
wm.Exit();
break;
default:
break;
}
}
system("pause");
return 0;
}
程序基本能编写下来,但是出现许多bug,在存在文件且数据不为空得情况下系统打开将会出现中断,而且添加职工时的溢出情况仍然存在,还有一个就是Worker**二级指针的声明以及m_EmpArr数组的使用,很模糊。