基于多态的职工管理系统(C++)

项目需求

职工管理系统可以用来管理公司内所有员工的信息

公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职责

  • 普通员工职责:完成经理交给的任务

  • 经理职责:完成老板交给的任务,并下发任务给员工

  • 老板职责:管理公司所有事务

管理系统中需要实现的功能如下:

  • 退出管理程序:退出当前管理系统
  • 增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为:职工编号、姓名、部门编号
  • 显示职工信息:显示公司内部所有职工的信息
  • 删除离职职工:按照编号删除指定的职工
  • 修改职工信息:按照编号修改职工个人信息
  • 查找职工信息:按照职工的编号或者职工的姓名进行查找相关的人员信息
  • 按照编号排序:按照职工编号,进行排序,排序规则由用户指定
  • 清空所有文档:清空文件中记录的所有职工信息 (清空前需要再次确认,防止误删)

分析设计

1.创建管理类

​ 管理类负责的内容如下:(app.c/app.h)

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

2.创建职工类

职工的分类为:普通员工、经理、老板(employ、manager、boss)

将三种职工抽象到一个类(worker)中,利用多态管理不同职工种类

职工的属性为:职工编号、职工姓名、职工所在部门编号

职工的行为为:岗位职责信息描述,获取岗位名称

3.执行文件

创建管理类的对象,调用里面的方法实现需求

4.注意事项

防止cin输入的数据类型不对导致代码崩溃

cout << “请输入您的选择:” << endl;
cin >> n;

//防止输入错误数据类型,导致死循环

int flag = 0;
while (cin.fail()) {
if (flag == 0)
cout << “请输入正确的数据类型” << endl;
cin.clear();
cin.ignore();
cin >> n;
flag++;
}

源码

职工管理系统.cpp

#include <iostream>
#include "app.h"

using namespace std;

int main() {
    
    
	app app;
	int n;
	while (true) {
    
    
		app.showMenu();
		cout << "请输入您的选择:" << endl;
		cin >> n;

		//防止输入错误数据类型,导致死循环
		int flag = 0;
		while (cin.fail()) {
    
    
			if (flag == 0)
				cout << "请输入正确的数据类型" << endl;
			cin.clear();
			cin.ignore();
			cin >> n;
			flag++;
		}

		switch (n) {
    
    
		case 0: //退出系统
			app.exitSystem();
			break;
		case 1: //添加职工
			app.addWorker();
			break;
		case 2: //显示职工
			app.showWorker();
			break;
		case 3: //删除职工
			app.delWorker();
			break;
		case 4: //修改职工
			app.changeWorker();
			break;
		case 5: //查找职工
			app.findWorker();
			break;
		case 6: //排序职工
			app.sortWorker();
			break;
		case 7: //清空文件
			app.clearFile();
			break;
		default:
			system("cls");
			break;
		}
	}

	return 0;
}

app.cpp

#include "app.h"

app::app()
{
    
    
	ifstream ifs(FILENAME, ios::in);

	//判断文件是否存在
	if (!ifs.is_open()) {
    
    
		cout << "文件不存在" << endl;
		this->workerNum = 0;
		this->workerArray = NULL;
		this->isEmpty = true;
		ifs.close();
		return;
	}

	//存在,是否为空
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
    
    
		cout << "文件为空" << endl;
		this->workerNum = 0;
		this->workerArray = NULL;
		this->isEmpty = true;
		ifs.close();
		return;
	}

	//存在,且不为空
	int num = this->getFilewWorkerNum();
	this->workerNum = num;

	//测试代码
	//cout << "职工人数为:" << num << endl;

	this->workerArray = new worker * [this->workerNum];//开辟空间
	this->initWorker();//将文件中的数据,存到数组中

	//测试代码
	//for (int i = 0; i < workerNum; i++)
	//{
    
    
	//	cout << "职工号: " << this->workerArray[i]->getId()
	//		<< " 职工姓名: " << this->workerArray[i]->getName()
	//		<< " 部门: " << this->workerArray[i]->getDeptName() << endl;
	//}

}

app::~app()
{
    
    

}

/*
* @brief 显示菜单
* @param 无
* @return 无
*/
void app::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;
}

/*
* @brief 退出系统
* @param 无
* @return 无
*/
void app::exitSystem() {
    
    
	cout << "欢迎下次使用" << endl;
	system("pause");
	exit(0);
}

/*
* @brief 添加职工
* @param 无
* @return 无
*/
void app::addWorker() {
    
    

	int addNum = 0;//添加职工数量
	cout << "请输入要添加的职工数量:" << endl;
	cin >> addNum;

	//防止输入错误数据类型,导致死循环
	int flag = 0;
	while (cin.fail()) {
    
    
		if (flag == 0)
			cout << "请输入正确的数据类型" << endl;
		cin.clear();
		cin.ignore();
		cin >> addNum;
		flag++;
	}

	if (addNum > 0) {
    
    
		int newSize = this->workerNum + addNum;//计算新空间大小
		worker** newSpace = new worker * [newSize];//开辟新空间

		//将原空间下数据存放到新空间下
		if (this->workerArray != NULL) {
    
    
			for (int i = 0; i < this->workerNum; i++) {
    
    
				newSpace[i] = this->workerArray[i];
			}
		}

		//添加新数据
		for (int i = 0; i < addNum; i++) {
    
    
			int id;
			string name;
			int deptId;

			cout << "请输入第" << i + 1 << "个新职工编号:" << endl;
			cin >> id;

			//防止输入错误数据类型,导致死循环
			flag = 0;
			while (cin.fail()) {
    
    
				if (flag == 0)
					cout << "请输入正确的数据类型" << endl;
				cin.clear();
				cin.ignore();
				cin >> id;
				flag++;
			}

			cout << "请输入第" << i + 1 << "个新职工姓名:" << endl;
			cin >> name;

			cout << "请选择该职工的岗位:" << endl;
			cout << "1、普通职工" << endl;
			cout << "2、经理" << endl;
			cout << "3、老板" << endl;
			worker* worker = NULL;

			//死循环,防止输入错误信息
			while (true) {
    
    
				cin >> deptId;
				//防止输入错误数据类型,导致死循环
				int flag = 0;
				while (cin.fail()) {
    
    
					if (flag == 0)
						cout << "请输入正确的数据类型" << endl;
					cin.clear();
					cin.ignore();
					cin >> deptId;
					flag++;
				}

				switch (deptId)
				{
    
    
				case 1://员工
					worker = new employee(id, name, deptId);
					break;
				case 2://经理
					worker = new manager(id, name, deptId);
					break;
				case 3://老板
					worker = new boss(id, name, deptId);
					break;
				default:
					cout << "输入有误,请重新输入" << endl;
					continue;
				}
				break;
			}
			//将创建的职工指针存放到数组中
			//该方法会提示缓冲区溢出,不过不影响程序执行,可以换成下面的语句解决
			//newSpace[this->workerNum + i] = worker;
			*(newSpace + this->workerNum + i) = worker;
		}

		delete[] this->workerArray;//释放原有空间

		this->workerArray = newSpace;//更改新空间的指向

		this->workerNum = newSize;//更新新的职工人数

		this->isEmpty = false;//更新文件状态

		cout << "成功添加" << addNum << "名新职工!" << endl;//提示信息

		this->saveFile();//保存数据到文件中
	}
	else {
    
    
		cout << "输入数据有误!" << endl;
	}
	system("pause");
	system("cls");
}

/*
* @brief 保存文件
* @param 无
* @return 无
*/
void app::saveFile() {
    
    

	ofstream ofs(FILENAME, ios::out);//创建输出流对象

	//将每个人的数据写入到文件中
	for (int i = 0; i < this->workerNum; i++) {
    
    
		ofs << this->workerArray[i]->getId() << " "
			<< this->workerArray[i]->getName() << " "
			<< this->workerArray[i]->getDeptId() << endl;
	}

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

/*
* @brief 获取文件中的职工人数
* @param 无
* @return 文件中的职工人数
*/
int app::getFilewWorkerNum() {
    
    

	ifstream ifs(FILENAME, ios::in);//创建输入流对象

	int id;
	string name;
	int deptId;
	int num = 0;

	//统计人数
	while (ifs >> id && ifs >> name && ifs >> deptId) {
    
    
		num++;
	}

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

	return num;
}

/*
* @brief 初始化职工
* @param 无
* @return 无
*/
void app::initWorker() {
    
    
	ifstream ifs(FILENAME, ios::in);//创建输入流对象

	int id;
	string name;
	int deptId;
	int index = 0;

	while (ifs >> id && ifs >> name && ifs >> deptId) {
    
    
		worker* worker = NULL;
		if (deptId == 1) {
    
    //普通员工
			worker = new employee(id, name, deptId);
		}
		else if (deptId == 2) {
    
    //经理
			worker = new manager(id, name, deptId);
		}
		else {
    
    //老板
			worker = new boss(id, name, deptId);
		}
		this->workerArray[index] = worker;
		index++;
	}
	ifs.close();
}

/*
* @brief 显示职工
* @param 无
* @return 无
*/
void app::showWorker() {
    
    

	if (this->isEmpty) {
    
    
		cout << "文件不存在或记录为空!" << endl;
	}
	else {
    
    
		for (int i = 0; i < this->workerNum; i++) {
    
    
			this->workerArray[i]->showInfo();
		}
	}
	system("pause");
	system("cls");
}

/*
* @brief 删除职工
* @param 无
* @return 无
*/
void app::delWorker() {
    
    

	if (this->isEmpty) {
    
    
		cout << "文件不存在或记录为空!" << endl;
	}
	else {
    
    
		cout << "请输入要删除的职工编号:" << endl;
		int id;
		cin >> id;

		//防止输入错误数据类型,导致死循环
		int flag = 0;
		while (cin.fail()) {
    
    
			if (flag == 0)
				cout << "请输入正确的数据类型" << endl;
			cin.clear();
			cin.ignore();
			cin >> id;
			flag++;
		}

		//查找职工是否存在
		int index = this->checkWorkerExist(id);

		if (index != -1) {
    
    
			for (int i = index; i < this->workerNum - 1; i++) {
    
    
				//数据前移
				this->workerArray[i] = this->workerArray[i + 1];
			}
			this->workerNum--;//更新数组中记录人员个数

			this->saveFile();//更新文件中的人员信息

			cout << "删除成功!" << endl;
		}
		else {
    
    
			cout << "删除失败,未找到该职工!" << endl;
		}
	}
	system("pause");
	system("cls");
}

/*
* @brief 检测职工是否存在
* @param 职工编号
* @return 职工所在数组中的位置,不存在返回-1
*/
int app::checkWorkerExist(int id) {
    
    
	int index = -1;
	for (int i = 0; i < this->workerNum; i++) {
    
    
		if (this->workerArray[i]->getId() == id) {
    
    
			index = i;
			break;
		}
	}
	return index;
}

/*
* @brief 修改职工
* @param 无
* @return 无
*/
void app::changeWorker() {
    
    

	if (this->isEmpty) {
    
    
		cout << "文件不存在或记录为空!" << endl;
	}
	else {
    
    
		cout << "请输入要修改的职工编号:" << endl;
		int id;
		cin >> id;

		//防止输入错误数据类型,导致死循环
		int flag = 0;
		while (cin.fail()) {
    
    
			if (flag == 0)
				cout << "请输入正确的数据类型" << endl;
			cin.clear();
			cin.ignore();
			cin >> id;
			flag++;
		}

		//查找职工是否存在
		int index = this->checkWorkerExist(id);
		if (index == -1) {
    
    
			cout << "修改失败,查无此人" << endl;
		}
		else {
    
    
			delete this->workerArray[index];//删除原有职工

			int newId = 0;
			string newName = "";
			int newDeptId = 0;

			cout << "查到:" << id << "号职工" << endl;
			cout << "请输入新的职工号:" << endl;
			cin >> newId;

			//防止输入错误数据类型,导致死循环
			flag = 0;
			while (cin.fail()) {
    
    
				if (flag == 0)
					cout << "请输入正确的数据类型" << endl;
				cin.clear();
				cin.ignore();
				cin >> newId;
				flag++;
			}

			cout << "请输入新的姓名:" << endl;
			cin >> newName;

			cout << "请输入新的部门:" << endl;
			cout << "1、普通员工" << endl;
			cout << "2、经理" << endl;
			cout << "3、老板" << endl;
			worker* worker = NULL;

			//死循环,防止输入错误信息
			while (true) {
    
    
				cin >> newDeptId;

				//防止输入错误数据类型,导致死循环
				flag = 0;
				while (cin.fail()) {
    
    
					if (flag == 0)
						cout << "请输入正确的数据类型" << endl;
					cin.clear();
					cin.ignore();
					cin >> newDeptId;
					flag++;
				}

				switch (newDeptId)
				{
    
    
				case 1://员工
					worker = new employee(newId, newName, newDeptId);
					break;
				case 2://经理
					worker = new manager(newId, newName, newDeptId);
					break;
				case 3://老板
					worker = new boss(newId, newName, newDeptId);
					break;
				default:
					cout << "输入有误,请重新输入" << endl;
					continue;
				}
				break;
			}

			this->workerArray[index] = worker;//保存新的职工信息
			cout << "修改成功!" << endl;
			this->saveFile();//更新文件中的职工信息
		}
	}
	system("pause");
	system("cls");
}

/*
* @brief 查找职工
* @param 无
* @return 无
*/
void app::findWorker() {
    
    

	if (this->isEmpty) {
    
    
		cout << "文件不存在或记录为空!" << endl;
	}
	else {
    
    
		cout << "请输入查找的方式:" << endl;
		cout << "1、按职工编号查找" << endl;
		cout << "2、按姓名查找" << endl;

		int select = 0;

		while (true) {
    
    
			cin >> select;

			//防止输入错误数据类型,导致死循环
			int flag = 0;
			while (cin.fail()) {
    
    
				if (flag == 0)
					cout << "请输入正确的数据类型" << endl;
				cin.clear();
				cin.ignore();
				cin >> select;
				flag++;
			}

			if (select == 1) {
    
    //按职工编号查找
				cout << "请输入要查找的职工编号:" << endl;
				int id;
				cin >> id;

				//防止输入错误数据类型,导致死循环
				flag = 0;
				while (cin.fail()) {
    
    
					if (flag == 0)
						cout << "请输入正确的数据类型" << endl;
					cin.clear();
					cin.ignore();
					cin >> id;
					flag++;
				}

				int index = this->checkWorkerExist(id);
				if (index != -1) {
    
    
					cout << "查找成功!该职工信息如下:" << endl;
					this->workerArray[index]->showInfo();
				}
				else {
    
    
					cout << "查无此人!" << endl;
				}
				break;
			}
			else if (select == 2) {
    
    //按姓名查找
				cout << "请输入要查找的姓名:" << endl;
				string name;
				cin >> name;

				bool flag = false;//标志是否查到

				for (int i = 0; i < this->workerNum; i++) {
    
    
					if (this->workerArray[i]->getName() == name) {
    
    
						cout << "查找成功!该职工信息如下:" << endl;
						this->workerArray[i]->showInfo();
						flag = true;
					}
				}
				if (flag == false) {
    
    
					cout << "查无此人!" << endl;
				}
				break;
			}
			else {
    
    
				cout << "输入有误,请重新输入" << endl;
				continue;
			}
		}

	}
	system("pause");
	system("cls");
}

/*
* @brief 排序职工
* @param 无
* @return 无
*/
void app::sortWorker() {
    
    
	if (this->isEmpty) {
    
    
		cout << "文件不存在或记录为空!" << endl;
	}
	else {
    
    
		cout << "请选择排序方式:" << endl;
		cout << "1、按职工号进行升序" << endl;
		cout << "2、按职工号进行降序" << endl;
		int select = 0;

		while (true) {
    
    
			cin >> select;

			//防止输入错误数据类型,导致死循环
			int flag = 0;
			while (cin.fail()) {
    
    
				if (flag == 0)
					cout << "请输入正确的数据类型" << endl;
				cin.clear();
				cin.ignore();
				cin >> select;
				flag++;
			}

			//升序排序
			if (select == 1) {
    
    
				for (int i = 0; i < this->workerNum; i++) {
    
    
					int min = i;
					for (int j = i + 1; j < this->workerNum; j++) {
    
    //找到最小值
						if (this->workerArray[min]->getId() > this->workerArray[j]->getId()) {
    
    
							min = j;
						}
					}
					if (min != i) {
    
    //交换位置
						worker* temp = this->workerArray[min];
						this->workerArray[min] = this->workerArray[i];
						this->workerArray[i] = temp;
					}
				}

				cout << "排序成功!" << endl;
				this->saveFile();//更新文件中的职工信息
				this->showWorker();//显示排序后的职工信息

				break;
			}

			//降序排序
			else if (select == 2) {
    
    
				for (int i = 0; i < this->workerNum; i++) {
    
    
					int max = i;
					for (int j = i + 1; j < this->workerNum; j++) {
    
    //找到最大值
						if (this->workerArray[max]->getId() < this->workerArray[j]->getId()) {
    
    
							max = j;
						}
					}
					if (max != i) {
    
    //交换位置
						worker* temp = this->workerArray[max];
						this->workerArray[max] = this->workerArray[i];
						this->workerArray[i] = temp;
					}
				}

				cout << "排序成功!" << endl;
				this->saveFile();//更新文件中的职工信息
				this->showWorker();//显示排序后的职工信息

				break;
			}
			else {
    
    
				cout << "输入有误,请重新输入" << endl;
				continue;
			}
		}
	}
	system("pause");
	system("cls");

}

/*
* @brief 清空文件
* @param 无
* @return 无
*/
void app::clearFile() {
    
    

	cout << "确认清空?" << endl;
	cout << "1、确认" << endl;
	cout << "2、返回" << endl;
	int select = 0;

	while (true) {
    
    
		cin >> select;

		//防止输入错误数据类型,导致死循环
		int flag = 0;
		while (cin.fail()) {
    
    
			if (flag == 0)
				cout << "请输入正确的数据类型" << endl;
			cin.clear();
			cin.ignore();
			cin >> select;
			flag++;
		}

		if (select == 1) {
    
    

			ofstream ofs(FILENAME, ios::trunc);//删除文件中的内容
			ofs.close();

			//删除堆区中的数据
			if (this->workerArray != NULL) {
    
    
				for (int i = 0; i < this->workerNum; i++) {
    
    
					if (this->workerArray[i] != NULL) {
    
    
						delete this->workerArray[i];
					}
				}
				this->workerNum = 0;
				delete[] this->workerArray;
				this->workerArray = NULL;
				this->isEmpty = true;
			}
			cout << "清空成功!" << endl;
			break;
		}
		else if (select == 2) {
    
    
			break;
		}
		else {
    
    
			cout << "输入有误,请重新输入" << endl;
			continue;
		}
	}
	system("pause");
	system("cls");
}

app.h

#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

#define FILENAME "workerFile.txt"

using namespace std;

class app
{
    
    
public:
	int workerNum;//职工人数
	worker** workerArray;//职工数组
	bool isEmpty;//标志文件是否为空

	app();

	~app();

	void showMenu();//显示菜单

	void exitSystem();//退出系统

	void addWorker();//添加职工

	void saveFile();//保存文件

	int getFilewWorkerNum();//获取文件中的人数

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

	void showWorker();//显示职工

	void delWorker();//删除职工

	int checkWorkerExist(int id);//检测职工是否存在

	void changeWorker();//修改职工

	void findWorker();//查找职工

	void sortWorker();//排序职工

	void clearFile();//清空文件

};

worker.cpp

#include "worker.h"

void worker::setId(int id) {
    
    
	this->id = id;
}

int worker::getId() {
    
    
	return this->id;
}

void worker::setName(string name) {
    
    
	this->name = name;
}

string worker::getName() {
    
    
	return this->name;
}

void worker::setDeptId(int deptId) {
    
    
	this->deptId = deptId;
}

int worker::getDeptId() {
    
    
	return this->deptId;
}

worker.h

#pragma once
#include <iostream>
using namespace std;

class worker
{
    
    
private:
	int id; //职工编号
	string name; //职工姓名
	int deptId; //职工所在部门名称编号

public:

	//构造函数
	void setId(int id);
	int getId();
	void setName(string name);
	string getName();
	void setDeptId(int deptId);
	int getDeptId();

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

employ.cpp

#include "employee.h"

employee::employee(int id, string name, int deptId) {
    
    
	this->setId(id);
	this->setName(name);
	this->setDeptId(deptId);
}

string employee::getDeptName() {
    
    
	return string("员工");
}

void employee::showInfo() {
    
    
	cout << "职工编号:" << this->getId()
		<< "\t职工姓名:" << this->getName()
		<< "\t岗位:" << this->getDeptName()
		<< "\t岗位职责:完成经理交给的任务" << endl;
}

employ.h

#pragma once
#include "worker.h"
class employee : public worker
{
    
    
public:
	//构造函数,初始化信息
	employee(int id, string name, int deptId);
	//显示个人信息
	void showInfo();
	//获取岗位名称
	string getDeptName();
};


manager.cpp

#include "manager.h"

manager::manager(int id, string name, int deptId) {
    
    
	this->setId(id);
	this->setName(name);
	this->setDeptId(deptId);
}

string manager::getDeptName() {
    
    
	return string("经理");
}

void manager::showInfo() {
    
    
	cout << "职工编号:" << this->getId()
		<< "\t职工姓名:" << this->getName()
		<< "\t岗位:" << this->getDeptName()
		<< "\t岗位职责:完成老板交给的任务,并下发任务给员工" << endl;
}

manager.h

#pragma once
#include "worker.h"
class manager : public worker
{
    
    
public:
	manager(int id, string name, int deptId);
	void showInfo();
	string getDeptName();
};


boss.cpp

#include "boss.h"

boss::boss(int id, string name, int deptId) {
    
    
	this->setId(id);
	this->setName(name);
	this->setDeptId(deptId);
}

string boss::getDeptName() {
    
    
	return string("老板");
}

void boss::showInfo() {
    
    
	cout << "职工编号:" << this->getId()
		<< "\t职工姓名:" << this->getName()
		<< "\t岗位:" << this->getDeptName()
		<< "\t岗位职责:公司管理" << endl;
}

boss.h

#pragma once
#include "worker.h"

class boss : public worker
{
    
    
public:
	boss(int id, string name, int deptId);
	void showInfo();
	string getDeptName();
};


猜你喜欢

转载自blog.csdn.net/qq_61228493/article/details/131997956