C++案例(2)——利用C++实现职工管理系统

发布时间:2023-02-27 15:00

一、需求分析

利用C++实现一个基于多态的职工管理系统。职工分为三类:普通员工、经理和老板。显示信息时,需要显示职工编号、姓名、岗位。
管理系统中需要实现的功能如下:

  • 退出管理系统
  • 增加职工信息
  • 显示职工信息
  • 删除离职员工
  • 修改职工信息
  • 查找职工信息
  • 按照编号排序
  • 清空管理系统

二、代码实现

2.1 创建管理类

管理类内容为:

  • 与用户的沟通菜单界面
  • 对职工增删改查的操作
  • 与文件的读写交互

在头文件和源文件中分别创建workManager.h头文件和workManager.cpp源文件。
在.h头文件中创建基本框架:

#pragma once		//防止头文件重复包含
#include

using namespace std;//标准命名空间

class WorkManager
{
public:
	//构造函数
	WorkManager();


	//析构函数
	~WorkManager();

};

在.cpp源文件中搭建基本框架:

#include\"workManager.h\"

WorkManager::WorkManager() {

}



WorkManager::~WorkManager() {

}

2.2 菜单

在workManager.h中添加成员函数void showMenu();
在workManager.cpp中实现该函数:

//显示菜单
void WorkManager::showMenu()
{
	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;
}

在主函数中调用该函数:

int main()
{
	WorkManager wm;//实例化类对象
	wm.showMenu();//调用展示菜单成员函数

	system(\"pause\");
	return 0;
}

2.3 主函数框架

在实现上述功能之前,首先需要搭建一下基本框架,基本框架主函数如下:

int main()
{
	WorkManager wm;//实例化类对象
	int choice = 0;//创建用户选择变量

	while (true) {
		wm.showMenu();//调用展示菜单成员函数
		cout << \"请输入您的选择:\" << endl;
		cin >> choice;
		switch (choice)
		{
			case 0:	//0、退出管理系统
				break;
			case 1:	//1、添加职工
				break;
			case 2:	//2、显示职工
				break;
			case 3:	//3、删除职工
				break;
			case 4:	//4、查找职工
				break;
			case 5:	//5、修改职工
				break;
			case 6:	//6、排序职工
				break;
			case 7:	//7、清空管理系统
				break;
			default:
				system(\"cls\");//清屏
				break;
		}


	}
	system(\"pause\");
	return 0;
}

2.4 退出功能

选择0则退出管理系统,在workManager.h中添加成员函数void ExitSystem();
在workManager.cpp中实现该函数:

//退出系统
void WorkManager::ExitSystem()
{
	cout << \"欢迎下次使用\" << endl;
	system(\"pause\");
	exit(0);//退出程序
}

case0中添加如下代码:

			case 0:	//0、退出管理系统
				wm.ExitSystem();
				break;

2.5 创建职工抽象类

在头文件和源文件中分别创建worker.h头文件和worker.cpp源文件。
在.h头文件中创建员工类:

#include
#include

using namespace std;

//职工抽象类
class Worker
{
public:
	//职工编号
	int m_Id;
	//职工姓名
	string m_Name;
	//部门编号
	int m_DeptId;

	//显示个人信息
	virtual void showInfo() = 0;//纯虚函数
	//获取岗位名称
	virtual string getDeptName() = 0;//纯虚函数
};

2.5.1 普通职工类

在头文件和源文件中分别创建employee.h头文件和employee.cpp源文件。
在.h头文件中创建普通职工类,继承自Worker抽象类:

//普通职工类
#include
#include\"worker.h\"

class Employee:public Worker
{
public:
	Employee(int id,string name,int deptId);  //构造函数

	//显示个人信息
	virtual void showInfo();
	//获取岗位名称
	virtual string getDeptName();

};

在.cpp源文件中定义相关函数:

#include\"employee.h\"


//构造函数
Employee::Employee(int id, string name, int deptId)
{
	//初始化
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = deptId;
}

//显示个人信息
void Employee::showInfo()
{
	cout<<\"职工编号:\"<<this->m_Id
		<<\"\\t职工姓名:\"<<this->m_Name
		<<\"\\t岗位:\"<<this->getDeptName()
}
//获取岗位名称
string Employee::getDeptName()
{
	return string(\"普通职工\");
}

2.5.2 经理类

在头文件和源文件中分别创建manager.h头文件和manager.cpp源文件。
在.h头文件中创建经理类,继承自Worker抽象类:

//经理类
#include
#include\"worker.h\"

class Manager :public Worker
{
public:
	Manager(int id, string name, int deptId);  //构造函数

	//显示个人信息
	virtual void showInfo();
	//获取岗位名称
	virtual string getDeptName();

};

在.cpp源文件中定义相关函数:

#include\"manager.h\"


//构造函数
Manager::Manager(int id, string name, int deptId)
{
	//初始化
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = deptId;
}

//显示个人信息
void Manager::showInfo()
{
	cout << \"职工编号:\" << this->m_Id
		<< \"\\t职工姓名:\" << this->m_Name
		<< \"\\t岗位:\" << this->getDeptName();
}
//获取岗位名称
string Manager::getDeptName()
{
	return string(\"经理\");
}

2.5.3 老板类

在头文件和源文件中分别创建boss.h头文件和boss.cpp源文件。
在.h头文件中创建老板类,同样继承自Worker抽象类:

//老板类
#include
#include\"worker.h\"

class Boss :public Worker
{
public:
	Boss(int id, string name, int deptId);  //构造函数

	//显示个人信息
	virtual void showInfo();
	//获取岗位名称
	virtual string getDeptName();

};

在.cpp源文件中定义相关函数:

#include\"boss.h\"


//构造函数
Boss::Boss(int id, string name, int deptId)
{
	//初始化
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = deptId;
}

//显示个人信息
void Boss::showInfo()
{
	cout << \"职工编号:\" << this->m_Id
		<< \"\\t职工姓名:\" << this->m_Name
		<< \"\\t岗位:\" << this->getDeptName()
}

//获取岗位名称
string Boss::getDeptName()
{
	return string(\"老板\");
}

2.6 添加职工

在WorkManager.h头文件中添加成员属性:

	//记录职工人数
	int m_Size;
	//职工数组指针
	Worker** m_EmployeeArray;

添加成员函数:

	//添加职工
	void addEmp();

在WorkManager.cpp源文件构造函数中初始化属性:

WorkManager::WorkManager() {
	//初始化属性
	this->m_Size = 0;
	this->m_EmployeeArray = NULL;

}

实现addEmp函数,实现批量添加函数:

void WorkManager::addEmp()
{
	cout << \"请输入添加职工数量:\" << endl;
	int addNum = 0;//保存用户的输入数量
	cin >> addNum;
	if (addNum > 0)
	{
		//计算添加新空间人数
		int newSize = this->m_Size + addNum;//新空间人数=原来记录人数+新增人数
		//开辟新空间【动态数组】
		Worker** newSpace = new Worker*[newSize];
		//将原来空间下的数据,拷贝到新空间下
		if (this->m_EmployeeArray != NULL) {
			for (int i = 0; i < this->m_Size; i++)
			{
				newSpace[i] = this->m_EmployeeArray[i];
			}
		}
		//批量添加新数据
		for (int i = 0; i < addNum; i++)
		{
			int id;//职工编号
			string name;//职工姓名
			int deptid;//部门
			cout << \"请输入第\" << i + 1 << \"个新职工编号:\" << endl;
			cin >> id;
			cout << \"请输入第\" << i + 1 << \"个新职工姓名:\" << endl;
			cin >> name;
			cout << \"请选择该职工的岗位:\" << endl;
			cout << \"1、普通职工\" << endl;
			cout << \"2、经理\" << endl;
			cout << \"3、老板\" << endl;
			cin >> deptid;

			Worker* worker = NULL;
			switch (deptid)
			{
			case 1:
				worker = new Employee(id, name, 1);
				break;
			case 2:
				worker = new Manager(id, name, 2);
				break;
			case 3:
				worker = new Boss(id, name, 3);
				break;
			default:
				break;
			}
			//将创建的员工指针保存到数组中
			newSpace[this->m_Size + i] = worker;

		}
		//释放原有空间
		delete[] this->m_EmployeeArray;
		//更改新空间的指向
		this->m_EmployeeArray = newSpace;
		//更新职工人数
		this->m_Size = newSize;
		//提示添加成功
		cout << \"成功添加\" << addNum << \"名新职工\" << endl;


	}
	else {
		cout << \"输入数据有误!\" << endl;
	}
	//按任意键、清屏
	system(\"pause\");
	system(\"cls\");
}

case1中修改代码为:

			case 1:	//1、添加职工
				wm.addEmp();
				break;

最后,可以完善一下析构函数(析构函数其实可写可不写):

//析构函数
WorkManager::~WorkManager() {
	if (this->m_EmployeeArray != NULL)
	{
		delete[] this->m_EmployeeArray;
		this->m_EmployeeArray = NULL;
	}
}

2.7 实现文件操作

将上述添加职工的功能进行保存,实现当程序关闭时依然能记住添加的职工。

2.7.1 设定文件路径

首先需要在workManager.h中包含头文件和宏定义(文件名):

#include
#define FILENAME \"empFile.txt\"

2.7.2 保存文件

添加成员函数:

	//保存文件
	void save();

实现保存文件save()函数:

void WorkManager::save()
{
	ofstream ofs;
	ofs.open(FILENAME, ios::out);
	for (int i = 0; i < this->m_Size; i++)
	{
		ofs << this->m_EmployeeArray[i]->m_Id << \" \"
			<< this->m_EmployeeArray[i]->m_Name << \" \"
			<< this->m_EmployeeArray[i]->m_DeptId << endl;
	}
	ofs.close();

}

最后,在addEmp()函数最后调用该函数:

		this->save();//保存

2.7.3 读取文件

若已经存在文件,则每次程序开始运行时,需要将文件中的数据读取到程序中,如不存在文件,则无需读取。分为三种情况:
①第一次使用,文件未创建;
②文件存在,但数据被用户清空;
③文件存在,且存有信息;

在WorkManager.h头文件中添加成员属性判断文件是否为空:

	//标志文件是否为空
	bool m_FileIsEmpty;

在WorkManager.cpp构造函数中添加代码:

ifstream ifs;
ifs.open(FILENAME, ios::in);

2.7.3.1 若文件未创建

在WorkManager.cpp构造函数中添加代码:

	//若文件不存在
	if (!ifs.is_open())
	{
		cout << \"文件不存在\" << endl;//测试输出
		//初始化属性
		this->m_Size = 0;//初始化人数
		this->m_FileIsEmpty = true;//初始化文件为空
		this->m_EmployeeArray = NULL;//初始化数组
		ifs.close();//关闭文件
		return;
	}

2.7.3.2 若文件存在但数据为空

在WorkManager.cpp构造函数中追加代码:【判断文件是否为空】

	//2、若文件存在,但没有数据
	char ch;
	ifs >> ch;
	if (ifs.eof())
	{
		cout << \"文件为空\" << endl;
		//初始化属性
		this->m_Size = 0;//初始化人数
		this->m_FileIsEmpty = true;//初始化文件为空
		this->m_EmployeeArray = NULL;//初始化数组
		ifs.close();//关闭文件
		return;
	}

然后在addEmp()函数后更新职工不为空标志:

		//更新标志【不为空】
		this->m_FileIsEmpty = false;

2.7.3.3 若文件存在且数据不为空

在WorkManager.h中添加成员函数:

	//统计文件中的人数
	int get_EmpNum();

在WorkManager.cpp中实现该函数:

int WorkManager::get_EmpNum()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	int id;//职工编号
	string name;//职工姓名
	int deptid;//部门

	int num = 0;//人数
	while (ifs>>id && ifs >>name && ifs >>deptid)
	{
		//统计人数变量
		num++;
	}

	ifs.close();
	return num;
}

在构造函数中追加代码:

	//3、若文件存在,并且记录数据
	int num = this->get_EmpNum();
	cout << \"职工人数:\" << num << endl;
	this->m_Size = num;//人数

然后根据职工的相关数据,初始化WorkerManager中的Worker** m_EmployeeArray指针。
在WorkManager.h中添加成员函数:

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

在WorkManager.cpp中实现该函数:

void WorkManager::init_Emp()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	int id;//职工编号
	string name;//职工姓名
	int deptid;//部门
	int index = 0;
	while (ifs >> id && ifs >> name && ifs >> deptid)
	{
		Worker* worker = NULL;
		switch (deptid)
		{
		case 1:
			worker = new Employee(id, name, 1);
			break;
		case 2:
			worker = new Manager(id, name, 2);
			break;
		case 3:
			worker = new Boss(id, name, 3);
			break;
		default:
			break;
		}
		this->m_EmployeeArray[index] = worker;
		index++;

	}
	ifs.close();//关闭文件
}

最后,在构造函数中追加代码:

	//根据职工数创建数组
	this->m_EmployeeArray = new Worker*[this->m_Size];//开辟空间
	//将数据存到数组中
	this->init_Emp();
	for (int i = 0; i < this->m_Size; i++)
	{
		cout << \"职工编号:\" << this->m_EmployeeArray[i]->m_Id
			<< \"姓名:\" << this->m_EmployeeArray[i]->m_Name
			<< \"部门编号:\" << this->m_EmployeeArray[i]->m_DeptId << endl;
	}

2.8 显示职工

在WorkManager.h中添加成员函数:

	//显示职工
	void showEmp();

在WorkManager.cpp中实现该函数:

//2、显示职工
void WorkManager::showEmp()
{
	if (this->m_FileIsEmpty) {
		cout << \"文件为空或不存在...\" << endl;
	}
	else
	{
		for (int i = 0; i < this->m_Size; i++)
		{
			this->m_EmployeeArray[i]->showInfo();//显示信息
			cout << endl;
		}
	}
	system(\"pause\");//请按任意键继续
	system(\"cls\");//清屏操作
}

case2中添加如下代码:

			case 2:	//2、显示职工
				wm.showEmp();
				break;

2.9 删除职工

在WorkManager.h中添加成员函数:

	//判断职工是否存在
	int isExist(int id);
	//删除职工
	void deleteEmp();

定义检测职工是否存在函数,若存在则返回职工的id,否则返回-1:

int WorkManager::isExist(int id)
{
	for (int i = 0; i < this->m_Size; i++)
	{	//若存在
		if (this->m_EmployeeArray[i]->m_Id == id)
		{
			return i;//返回下标编号
		}

	}
	return -1;//如果没有找到
}

定义删除职工函数:

//3、删除职工
void WorkManager::deleteEmp()
{
		cout << \"请输入要删除的联系人ID:\" << endl;
		int id;
		cin >> id;
		int ret = isExist(id);//判断联系人是否存在
		if (ret != -1) {
			//查到了,则删除数据(利用后覆盖前实现)
			for (int i = ret; i < this->m_Size; i++)
			{
				//数据迁移
				this->m_EmployeeArray[i] = m_EmployeeArray[i + 1];
			}
			this->m_Size--;//更新通讯录中人员数
			//同步更新到文件中
			this->save();
			cout << \"删除成功\" << endl;
		}
		else {
			//未查到
			cout << \"删除失败,未查到该职工...\" << endl;
		}
		system(\"pause\");//请按任意键继续
		system(\"cls\");//清屏操作


}

case3中添加如下代码:

			case 3:	//3、删除职工
				wm.deleteEmp();
				break;

2.10 修改职工

在WorkManager.h中添加成员函数:

	//修改职工
	void modifyEmp();

定义修改职工函数:

//4、修改职工
void WorkManager::modifyEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << \"文件不存在或记录为空!\" << endl;
	}
	else {

		cout << \"请输入要修改的职工ID:\" << endl;
		int id;
		cin >> id;
		int ret = isExist(id);//判断职工是否存在
		if (ret != -1) {
			//查到了,则修改数据
			//delete this->m_EmployeeArray[ret];//这里可以清空内容再修改也可以不清空修改
			int id;//职工编号
			string name;//职工姓名
			int deptid;//部门
			cout << \"请输入新的新职工编号:\" << endl;
			cin >> id;
			cout << \"请输入新的新职工姓名:\" << endl;
			cin >> name;
			cout << \"请选择该职工的新岗位:\" << endl;
			cout << \"1、普通职工\" << endl;
			cout << \"2、经理\" << endl;
			cout << \"3、老板\" << endl;
			cin >> deptid;

			Worker* worker = NULL;
			switch (deptid)
			{
			case 1:
				worker = new Employee(id, name, 1);
				break;
			case 2:
				worker = new Manager(id, name, 2);
				break;
			case 3:
				worker = new Boss(id, name, 3);
				break;
			default:
				break;
			}
			//更新数据到数组中
			this->m_EmployeeArray[ret] = worker;
			cout << \"修改成功!\" << endl;
			//保存到文件中
			this->save();


		}
	else {
		//未查到
		cout << \"修改失败,未查到该联系人\" << endl;
		}
	}
	system(\"pause\");//请按任意键继续
	system(\"cls\");//清屏操作
}

case4中添加如下代码:

			case 4:	//4、查找职工
				wm.modifyEmp();
				break;

2.11 查找职工

在WorkManager.h中添加成员函数:

	//查找职工
	void findEmp();

定义查找职工函数:

//5、查找职工
void WorkManager::findEmp() 
{
	if (this->m_FileIsEmpty)
	{
		cout << \"文件不存在或记录为空!\" << endl;
	}
	else {
		cout << \"请输入查找的方式:\" << endl;
		cout << \"1、按照职工编号查找\" << endl;
		cout << \"2、按照职工姓名查找\" << endl;
		int select = 0;
		cin >> select;
		if (select == 1)
		{
			//按照编号查找
			cout << \"请输入要查找的职工编号:\" << endl;
			int id;
			cin >> id;
			int ret = isExist(id);//判断职工是否存在
			if (ret != -1) {
				//查到了,则显示数据
				this->m_EmployeeArray[ret]->showInfo();
			}
			else {
				cout << \"查找失败,查无此人...\" << endl;
			}
		}
		else if (select == 2)
		{
			//按照姓名查找
			cout << \"请输入要查找的职工姓名:\" << endl;
			string name;
			cin >> name;
			//加入判断标志判断是否查到【防止重复打印查无此人】
			bool flag = false;

			//判断职工是否存在
			for (int i = 0; i < this->m_Size; i++)
			{	//若存在
				if (this->m_EmployeeArray[i]->m_Name == name)
				{
					//查到了,则显示数据
					flag = true;

					this->m_EmployeeArray[i]->showInfo();
					cout << endl;
				}
			}
		if(flag==false)
		{
			cout << \"查找失败,查无此人...\" << endl;
		}

		}
		else {
			//输入有误
			cout << \"输入错误\" << endl;
		}

	}
	system(\"pause\");//请按任意键继续
	system(\"cls\");//清屏操作

}

case5中修改代码为:

			case 5:	//5、查找职工
				wm.findEmp();
				break;

2.12 职工排序

在WorkManager.h中添加成员函数:

	//排序职工
	void sortEmp();

使用选择排序算法定义职工排序函数:

//6、排序职工
void WorkManager::sortEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << \"文件不存在或记录为空!\" << endl;
	}
	else {
		cout << \"请输入排序的方式:\" << endl;
		cout << \"1、按照职工编号升序\" << endl;
		cout << \"2、按照职工编号降序\" << endl;
		int select = 0;
		cin >> select;
		//选择排序
		for (int i = 0; i < m_Size; i++)
		{
			int minOrmax = i;//声明最小值或最大值下标
			for (int j = i + 1; j < this->m_Size; j++)
			{
				//升序
				if (select == 1)
				{
					if (this->m_EmployeeArray[minOrmax]->m_Id > this->m_EmployeeArray[j]->m_Id)
					{
						minOrmax = j;
					}
				}
				//降序
				else {
					if (this->m_EmployeeArray[minOrmax]->m_Id < this->m_EmployeeArray[j]->m_Id)
					{
						minOrmax = j;
					}
				}
			}
			//判断一开始认定的最小值或最大值是否为计算的最小值或最大值,若否则交换数据
			if (i != minOrmax)
			{
				Worker* temp = this->m_EmployeeArray[i];
				this->m_EmployeeArray[i] = this->m_EmployeeArray[minOrmax];
				this->m_EmployeeArray[minOrmax] = temp;
			}
		}
		cout << \"排序成功!排序后的结果为:\" << endl;
		this->showEmp();//显示职工信息
		this->save();//保存到文件中
	}

}

case6中修改代码为:

			case 6:	//6、排序职工
				wm.sortEmp();
				break;

2.13 清空系统

在WorkManager.h中添加成员函数:

	//清空系统
	void clearEmp();

定义清空系统函数:【这里需要同时清空文件和堆区数据】

//7、清空管理系统
void WorkManager::clearEmp()
{
	cout << \"确定要清空吗?\" << endl;
	cout << \"1、确定\" << endl;
	cout << \"2、取消\" << endl;
	int select = 0;
	cin >> select;
	if (select == 1)
	{
		//清空文件
		ofstream ofs(FILENAME, ios::trunc);//删除文件后再重新创建(清空)
		ofs.close();
		//清空数据
		if (this->m_EmployeeArray != NULL)
		{
			//删除堆区的每个职工对象
			for (int i = 0; i < this->m_Size; i++)
			{
				if (this->m_EmployeeArray[i] != NULL)
				{
					delete this->m_EmployeeArray[i];
				}
			}
			//删除堆区数组指针
			delete[] this->m_EmployeeArray;
			this->m_EmployeeArray = NULL;
			this->m_Size = 0;//人数置为0
			this->m_FileIsEmpty = true;//标志为空
		}
		cout << \"清空成功\" << endl;
	}

	system(\"pause\");//请按任意键继续
	system(\"cls\");//清屏操作

}

同时,需要将析构函数也进行相应修改:

//析构函数
WorkManager::~WorkManager() {
	if (this->m_EmployeeArray != NULL)
	{
		for (int i = 0; i < this->m_Size; i++)
		{
			if (this->m_EmployeeArray[i] != NULL)
			{
				delete this->m_EmployeeArray[i];
			}
		}
		delete[] this->m_EmployeeArray;
		this->m_EmployeeArray = NULL;
	}
}

case7中修改代码为:

			case 7:	//7、清空管理系统
				wm.clearEmp();
				break;

三、效果演示

部分效果如下:
\"C++案例(2)——利用C++实现职工管理系统_第1张图片\"

如果没有看懂的话,完整代码可以参考:https://download.csdn.net/download/didi_ya/80135966


ok,以上便是本文的全部内容了,如果对你有所帮助,记得点个赞哟~

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号