适合初学者的经典C++项目-基于多态的职工管理系统

01 写在前面

对于C++初学者来说,学完基本的语法后,应该及时地找到适合自己的项目尝试着自己去练习;一方面,可以巩固刚刚学习的知识点,另一方面,可以让自己初步的了解实际开发中是怎样完成自己的工作的。
但是,对于我们初学者来说,找到一个适合自己现阶段的项目又有点困难或者说纠结,同时,有的时候会出现一些莫名其妙的问题。这些问题在我学习过程中深有体会,拿我今天分享的这个项目为例。
这个项目是我在学完C++基本语法后,跟着B站上黑马程序员敲的。我记得那个下午,当我写到void WorkManager::AddEmp()(项目中的一个函数,后文将提到)时,我把for循环的范围搞错了,但是在测试这个函数时一切仿佛很正常,我就继续往后面写,但是在后面的一个测试里,出现了问题,职工的信息并没有成功写入文件中,职工人数始终为0,所以,我不得不从当前的位置往前排查。我反复检查,并没有发现自己的问题,所以,我不得不,把视频调回去,重新的看,去和老师的代码一行一行的对。最后,终于找到了问题所在。但是,我因此花了一下午的时间去排查问题。我很幸运能够找到问题并完成这个项目,但是,有的小伙伴可能就不太幸运了,一直没有找到问题,以致想舍弃项目,当又有点舍不得,毕竟自己花了很长时间。这种情况应该在许多初学者身上时常遇到,比如正在看这篇博客的你(手动狗头)。
所以,这篇文章一方面是帮助初学者找到适合自己的项目,另一方面,帮助一些和我一样在这个项目中出现了问题但自己一直没有找到的小伙伴。当然,我自己是个菜鸡,能力有限,有些地方可能出现纰漏、文章可能写的不够详细、或者看完后依然没有找到自己项目的问题所在,欢迎大家友好讨论、私信;但,对于键盘侠、杠精,建议现在就离开,以免浪费彼此的时间,谢谢!
废话少讲(哈哈哈,一不小心就已经讲了这么多废话),直接上代码

02 代码分析

2.1 项目实现的功能介绍

本项目的职工管理系统和将实现8项功能:
1 增加职工信息;
2 显示职工信息;
3 删除离职职工;
4 修改职工信息;
5 查找职工信息;
6 按照编号排序;
7 清空所有文档;
8 退出本次管理;
总结: 完成对信息的增删改查

2.2 头文件

本次项目中包含5个头文件,下面我将一一介绍。

  • Worker.h
    创建一个职工的基类。其中包含3个成员变量,分别表示职工的3个基本信息:编号、姓名、所在部门编号,其中,不同的职工有不同的职位(1表示普通职工,2表示经理,3表示老板);另外,包含两个虚函数,他们分别实现显示职工信息,获取职工部门信息。
#pragma once
#include <iostream>
#include <string>
using namespace std;

class Worker
{
public:
	virtual void ShowInfo() = 0;//显示职工信息
	virtual string GetDeptName() = 0;//获取职工部门信息

	int m_id;//职工编号
	string m_name;//职工名字
	int m_deptid;//职工所在部门的编号
};
  • Employee.h
    创建一个继承了Worker的子类,其中包含3个成员函数,其中2个是继承父类的虚函数,另外一个是构造函数来初始化对象。
#pragma once
#include "Worker.h"

class Employee :public Worker
{
public:
	Employee(int id, string name, int deptid);
	virtual void ShowInfo();
	virtual string GetDeptName();
};
  • Manager.h
    同Employee.h一样,都是创建继承了Worker的子类
#pragma once
#include "Worker.h"

class Manager :public Worker
{
public:
	Manager(int id, string name, int deptid);
	virtual void ShowInfo();
	virtual string GetDeptName();
};
  • Boss.h
    同Employee.h一样,都是创建继承了Worker的子类
#pragma once
#include "Worker.h"

class Manager :public Worker
{
public:
	Manager(int id, string name, int deptid);
	virtual void ShowInfo();
	virtual string GetDeptName();
};
  • WorkManager.h
    创建一个WorkManager的类,这也是本次项目中的核心,实现本项目的核心功能,之所以把这些功能封装成一个类,是为了方便管理。该类中包含3个成员变量,分别用于:记录文件中的人数,员工数组指针,标示文件是否为空的bool值;包含了15个成员函数,其中两个是构造函数和析构函数,其他的成员函数将实现的功能有:菜单显示、退出程序、添加成员、保存文件、统计人数、初始化职工、显示职工信息、删除职工、判断职工是否存在、修改职工信息、查找职工、根据职工号对职工进行排序、清空文件。后文将讲解这些函数到底是怎样实现的,这也是本项目的核心。
#pragma once	
#include <iostream>
#include <fstream>
#include "Worker.h"
#define FILENAME "EmpFile.txt"
using namespace std;

class WorkManager
{
public:
	WorkManager();
	void ShowMenu();//菜单展示
	void ExitSystem();//退出程序
	void AddEmp();//添加成员
	void save();//保存文件
	int GetEmpNum();//统计人数
	void InitEmp();//初始化职工
	void ShowEmp();//显示职工信息
	void DelEmp();//删除职工
	int IsExist(int deptid);//按照编号判断职工是否存在;如果存在,返回职工在数组中的编号;如果不存在,返回-1
	void ModEmp();//修改职工信息
	void FindEmp();//查找职工
	void SortEmp();//排序职工
	void CleanFile();//清空文件
	~WorkManager();

	int m_empnum;//记录文件中的人数
	Worker** m_emparray;//员工数组指针
	bool m_FileIsEmpty;//标志文件是否为空
};

2.3 源文件

源文件中包含程序的入口以及对头文件中声明的函数具体实现一下。因为我在敲代码的时候尽量都带上了注释,一些内容完全可以自己理解,所以这里我不再一一讲解每行,而是,挑出里面的重点内容、难点内容讲解,如若有什么疑问或者程序有什么改进的地方,欢迎大家友好讨论、私信。

  • main.cpp
    程序的入口,我们在开始的时候将提供下方这样的界面:
     系统界面
    用户将选择自己想实现的功能,我们拿一个变量来接收用户的选项,通过选择结构调用对应的函数。
#define _CRT_SECURE_NO_WARNINGS 1
#include "WorkManager.h"
#include "Worker.h"
#include "Employee.h"
#include "Manager.h"
#include "Boss.h"

int main()
{	//测试代码
	//	Worker* worker = new Employee(1, "张三", 1);
	//	worker->ShowInfo();
	//	delete worker;
	//	worker = NULL;
	//
	//	worker = new Manager(1, "张三", 1);
	//	worker->ShowInfo();
	//	delete worker;
	//	worker = NULL;
	//
	//	worker = new Boss(1, "张三", 1);
	//	worker->ShowInfo();
	//	delete worker;
	//	worker = NULL;

	WorkManager wm;
	int num;//接收用户的选项
	while (true)
	{
		wm.ShowMenu();
		cout << "请输入你的选项:" << endl;
		cin >> num;
		switch (num)
		{
		case 0:
			wm.ExitSystem();
			break;
		case 1:
			wm.AddEmp();
			break;
		case 2:
			wm.ShowEmp();
			break;
		case 3:
			//cout << wm.IsExist(1) << endl;//测试代码
			wm.DelEmp();
			break;
		case 4:
			wm.ModEmp();
			break;
		case 5:
			wm.FindEmp();
			break;
		case 6:
			wm.SortEmp();
			break;
		case 7:
			wm.CleanFile();
			break;
		default:
			system("cls");
			break;
		}
	}
	system("pause");
	return 0;
}
  • Emloyee.cpp
    对普通职工这个对象进行初始化、显示职工信息、获取职工部门
#define _CRT_SECURE_NO_WARNINGS 1
#include "Employee.h"
using namespace std;

Employee::Employee(int id, string name, int deptid)
{
	m_id = id;
	m_name = name;
	m_deptid = deptid;
}

void Employee::ShowInfo()
{
	cout << "员工的编号为:\t" << this->m_id
		<< "\t职工的名字:" << this->m_name
		<< "\t岗位:" << this->GetDeptName()
		<< "\t岗位职责:完成经理交给的任务" << endl;
}

string Employee::GetDeptName()
{
	return string("员工");
}
  • Manager.cpp
    对经理对象这个进行初始化、显示职工信息、获取职工部门
#define _CRT_SECURE_NO_WARNINGS 1
#include "Manager.h"

Manager::Manager(int id, string name, int deptid)
{
	m_id = id;
	m_name = name;
	m_deptid = deptid;
}
void Manager::ShowInfo()
{
	cout << "员工的编号为:\t" << this->m_id
		<< "\t职工的名字:" << this->m_name
		<< "\t岗位:" << this->GetDeptName()
		<< "\t岗位职责:完成老板交给的任务,并将任务分配给下面的员工" << endl;
}
string Manager::GetDeptName()
{
	return string("经理");
}
  • Boss.cpp
    对老板这个对象进行初始化、显示职工信息、获取职工部门
#define _CRT_SECURE_NO_WARNINGS 1
#include "Boss.h"

Boss::Boss(int id, string name, int deptid)
{
	m_id = id;
	m_name = name;
	m_deptid = deptid;
}

void Boss::ShowInfo()
{
	cout << "员工的编号为:\t" << this->m_id
		<< "\t职工的名字:" << this->m_name
		<< "\t岗位:" << this->GetDeptName()
		<< "\t岗位职责:完成公司内的各种大小问题" << endl;
}

string Boss::GetDeptName()
{
	return string("总裁");
}
  • WorkManager.cpp
    这是函数的核心,对头文件中声明的15个成员函数进行具体实现,现在来讲解一下里面的重难点。

重难点1:构造函数

WorkManager::WorkManager()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	
	//文件不存在的情况
	if (!ifs.is_open())
	{
		//cout << "文件不存在" << endl;//测试代码
		this->m_FileIsEmpty = true;
		this->m_empnum = 0;//初始化人数
		this->m_emparray = NULL;//初始化数组指针
		ifs.close();
		return;
	}

	//文件存在但为空的情况
	char ch;
	ifs >> ch;
	if (ifs.eof())
	{
		//cout << "文件为空" << endl;//测试代码
		this->m_FileIsEmpty = true;
		this->m_empnum = 0;//初始化人数
		this->m_emparray = NULL;//初始化数组指针
		ifs.close();
		return;
	}

	//文件存在且有数据
	this->m_empnum = this->GetEmpNum();
	//cout << "职工人数为:" << this->m_empnum << endl;//测试代码
	this->m_emparray = new Worker * [this->m_empnum];
	this->InitEmp();

	测试代码
	//for (int i = 0; i < this->m_empnum; i++)
	//{
	//	cout << "职工号为:" << this->m_emparray[i]->m_id
	//		<< "职工姓名为:" << this->m_emparray[i]->m_name
	//		<< "部门编号为:" << this->m_emparray[i]->m_deptid << endl;
	//}
}

首先写入一个文件(其中FILENAME是我们在头文件中已经定义了的文件路径),文件分为三种状态:
1 文件不存在
2 文件存在但是记录为空
3 文件存在且记录不为空
前两种情况我们需要对成员变量进行初始化并关闭文件。
当文件不为空且有记录的时候,我们需要将文件中的数据写进我们的m_emparray数组中,这里我们调用封装好初始化数组的函数InitEmp()。

重难点2:增加新职工

void WorkManager::AddEmp()
{
	cout << "请输入增加员工数量:" << endl;
	int add_num = 0;
	cin >> add_num;
	if (add_num > 0)
	{
		//计算新空间的大小
		int new_size = this->m_empnum + add_num;

		//开辟新空间
		Worker** new_space = new Worker*[new_size];

		//将原来空间下的内容存放到新的空间中
		if (this->m_emparray != NULL)
		{
			for (int i = 0; i < this->m_empnum; i++)
			{
				new_space[i] = this->m_emparray[i];
			}
		}

		//输入数据
		for (int i = 0; i < add_num; i++)
		{
			int id = 0;
			string name;
			int deptid = 0;
			cout << "请输入第" << i + 1 << "个新职工编号" << endl;
			cin >> id;
			cout << "请输入第" << i + 1 << "个新职工姓名" << endl;
			cin >> name;
			cout << "请输入第" << i + 1 << "个新职工岗位" << 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;
			}
			new_space[this->m_empnum + i] = worker;
		}
		delete[] this->m_emparray;//释放原有空间
		this->m_emparray = new_space;//更新新的空间指向
		this->m_empnum = new_size;//更新新的个数
		this->m_FileIsEmpty = false;//更新职工不为空标志
		cout << "成功添加" << add_num << " 名新职工" << endl;
		this->save();
	}
	else
	{
		cout << "输入的数字有误" << endl;
	}
	system("pause");
	system("cls");
}

首先,询问用户将增加几名员工;如果员工人数输入的合理,我们将增加员工,如果输入的数字不合理,输出提示信息并返回上一级。
然后,根据新增人数开辟新的空间,第一步,将原来成员信息存放到新的空间中;第二步,提示用户输入对应的信息,并用局部变量接收这些信息;第三步,根据输入的职工部门编号创建对应的职工,并将职工放进职工数组中;第四步,释放原来的空间,更新新的空间、新的人数、新的职工是否为空的标志。

重难点3:初始化职工

void WorkManager::InitEmp()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	int id;
	string name;
	int deptid;
	int idex = 0;
	while (ifs >> id && ifs >> name && ifs >> deptid)
	{
		Worker* worker = NULL;
		//根据不同的部门id创建不同的对象
		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->m_emparray[idex] = worker;
		idex++;
	}
}

在开始项目时,我们需要将文件中职工的信息录入到数组中,以及增加职工时,我们要讲原来数组的信息更新到新数组中,他们实现的功能一样,所以,我们干脆把这相同的功能封装成本函数。
值得注意的是,我们需要根据职工部门编号创建不同的对象。

重难点4:返回职工编号

int WorkManager::IsExist(int deptid)
{
	int index = -1;
	for (int i = 0; i < this->m_empnum; i++)
	{
		if (this->m_emparray[i]->m_id == deptid)
		{
			index = i;
			break;
		}
	}
	return index;
}

在项目中删除职工信息、查找职工、修改职工信息,我们都需要通过职工编号来实现,所以,我们干脆也把这个功能封装为一个函数

重难点5:删除职工

void WorkManager::DelEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空" << endl;
	}
	else
	{
		//按照职工编号删除
		cout << "请输入你想删掉的职工号:" << endl;
		int id = 0;
		cin >> id;
		int index = this->IsExist(id);
		if (index != -1)
		{
			for (int i = index; i < this->m_empnum - 1; i++)
			{
				this->m_emparray[i] = this->m_emparray[i + 1];
			}
			this->m_empnum--;
			if (this->m_empnum == 0)
			{
				this->m_FileIsEmpty = true;
			}
			this->save();//删除时候同步数据到文件中
			cout << "删除成功" << endl;
		}
		else
		{
			cout << "删除失败,未能找到该职工" << endl;
		}
	}
	system("pause");
	system("cls");
}

这里我讲一下删除职工的基本思路,根据提供的职工编号,从这个编号开始,我们将数组后面的信息往前面覆盖一个位置,最后,职工数量将减去对应的值。

重点6:排序

void WorkManager::SortEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空" << endl;
		system("pause");
		system("cls");
	}
	else
	{
		//分布排序
		cout << "请选择排序方式:" << endl;
		cout << "1 按照职工号进行升序" << endl;
		cout << "2 按照职工号进行降序" << endl;
		int select = 0;
		cin >> select;
		for (int i = 0; i < m_empnum; i++)
		{
			int min_or_max = i;
			for (int j = i + 1; j < m_empnum; j++)
			{
				if (select == 1)//升序
				{
					if (m_emparray[min_or_max]->m_id > m_emparray[j]->m_id)
					{
						min_or_max = j;
					}
				}
				else//降序
				{
					if (m_emparray[min_or_max]->m_id < m_emparray[j]->m_id)
					{
						min_or_max = j;
					}
				}
			}
			if (i != min_or_max)
			{
				Worker* temp = m_emparray[i];
				m_emparray[i] = m_emparray[min_or_max];
				m_emparray[min_or_max] = temp;
			}
		}
		cout << "排序成功,排序后的结果:" << endl;
		this->save();
		this->ShowEmp();
	}
}

这里我为了省事,我用的排序方法是分布排序,这种排序可能性能稍差,你可以根据你个人的需求去优化。

重点7:析构函数

WorkManager::~WorkManager()
{
	if (this->m_emparray != NULL)
	{
		for (int i = 0; i < this->m_empnum; i++)
		{
			if (this->m_emparray[i] != NULL)
			{
				delete this->m_emparray[i];
				this->m_emparray[i] = NULL;
			}
		}
		this->m_empnum = 0;
		delete[] this->m_emparray;
		this->m_emparray = NULL;
		this->m_FileIsEmpty = true;
	}
}

在执行完程序时,我们需要把在堆区申请的对象空间释放、对象数组空间释放,职工人数置为0,文件为空标志置为true.

WorkManager.cpp完整代码

#define _CRT_SECURE_NO_WARNINGS 1
#include "WorkManager.h"
#include "Employee.h"
#include "Manager.h"
#include "Boss.h"

WorkManager::WorkManager()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	
	//文件不存在的情况
	if (!ifs.is_open())
	{
		//cout << "文件不存在" << endl;//测试代码
		this->m_FileIsEmpty = true;
		this->m_empnum = 0;//初始化人数
		this->m_emparray = NULL;//初始化数组指针
		ifs.close();
		return;
	}

	//文件存在但为空的情况
	char ch;
	ifs >> ch;
	if (ifs.eof())
	{
		//cout << "文件为空" << endl;//测试代码
		this->m_FileIsEmpty = true;
		this->m_empnum = 0;//初始化人数
		this->m_emparray = NULL;//初始化数组指针
		ifs.close();
		return;
	}

	//文件存在且有数据
	this->m_empnum = this->GetEmpNum();
	//cout << "职工人数为:" << this->m_empnum << endl;//测试代码
	this->m_emparray = new Worker * [this->m_empnum];
	this->InitEmp();

	测试代码
	//for (int i = 0; i < this->m_empnum; i++)
	//{
	//	cout << "职工号为:" << this->m_emparray[i]->m_id
	//		<< "职工姓名为:" << this->m_emparray[i]->m_name
	//		<< "部门编号为:" << this->m_emparray[i]->m_deptid << endl;
	//}
}

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;
}

void WorkManager::ExitSystem()
{
	cout << "欢迎你的下次使用" << endl;
	system("pause");
	exit(0);
}

void WorkManager::AddEmp()
{
	cout << "请输入增加员工数量:" << endl;
	int add_num = 0;
	cin >> add_num;
	if (add_num > 0)
	{
		//计算新空间的大小
		int new_size = this->m_empnum + add_num;

		//开辟新空间
		Worker** new_space = new Worker*[new_size];

		//将原来空间下的内容存放到新的空间中
		if (this->m_emparray != NULL)
		{
			for (int i = 0; i < this->m_empnum; i++)
			{
				new_space[i] = this->m_emparray[i];
			}
		}

		//输入数据
		for (int i = 0; i < add_num; i++)
		{
			int id = 0;
			string name;
			int deptid = 0;
			cout << "请输入第" << i + 1 << "个新职工编号" << endl;
			cin >> id;
			cout << "请输入第" << i + 1 << "个新职工姓名" << endl;
			cin >> name;
			cout << "请输入第" << i + 1 << "个新职工岗位" << 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;
			}
			new_space[this->m_empnum + i] = worker;
		}
		delete[] this->m_emparray;//释放原有空间
		this->m_emparray = new_space;//更新新的空间指向
		this->m_empnum = new_size;//更新新的个数
		this->m_FileIsEmpty = false;//更新职工不为空标志
		cout << "成功添加" << add_num << " 名新职工" << endl;
		this->save();
	}
	else
	{
		cout << "输入的数字有误" << endl;
	}
	system("pause");
	system("cls");
}

void WorkManager::save()
{
	ofstream ofs;
	ofs.open(FILENAME, ios::out); // 用输出的方式打开文件  -- 写文件

	//将每个人数据写入到文件中
	for (int i = 0; i < this->m_empnum; i++)
	{
		ofs << this->m_emparray[i]->m_id << " "
			<< this->m_emparray[i]->m_name << " "
			<< this->m_emparray[i]->m_deptid << endl;
	}

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

}

int WorkManager::GetEmpNum()
{
	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;
}

void WorkManager::InitEmp()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	int id;
	string name;
	int deptid;
	int idex = 0;
	while (ifs >> id && ifs >> name && ifs >> deptid)
	{
		Worker* worker = NULL;
		//根据不同的部门id创建不同的对象
		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->m_emparray[idex] = worker;
		idex++;
	}
}

void WorkManager::ShowEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空" << endl;
	}
	else
	{
		for (int i = 0; i < m_empnum; i++)
		{
			//利用多态调用接口
			this->m_emparray[i]->ShowInfo();
		}
	}
	system("pause");
	system("cls");
}

int WorkManager::IsExist(int deptid)
{
	int index = -1;
	for (int i = 0; i < this->m_empnum; i++)
	{
		if (this->m_emparray[i]->m_id == deptid)
		{
			index = i;
			break;
		}
	}
	return index;
}

void WorkManager::DelEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空" << endl;
	}
	else
	{
		//按照职工编号删除
		cout << "请输入你想删掉的职工号:" << endl;
		int id = 0;
		cin >> id;
		int index = this->IsExist(id);
		if (index != -1)
		{
			for (int i = index; i < this->m_empnum - 1; i++)
			{
				this->m_emparray[i] = this->m_emparray[i + 1];
			}
			this->m_empnum--;
			if (this->m_empnum == 0)
			{
				this->m_FileIsEmpty = true;
			}
			this->save();//删除时候同步数据到文件中
			cout << "删除成功" << endl;
		}
		else
		{
			cout << "删除失败,未能找到该职工" << endl;
		}
	}
	system("pause");
	system("cls");
}

void WorkManager::ModEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空" << endl;
	}
	else
	{
		cout << "请输入修改职工的编号" << endl;
		int id;
		cin >> id;
		int ret = this->IsExist(id);
		if (ret != -1)
		{
			//查找到编号的职工
			delete this->m_emparray[ret];
			int new_id = 0;
			string new_name = "";
			int new_deptid = 0;
			cout << "查到: " << id << "号职工,请输入新职工号:" << endl;
			cin >> new_id;
			cout << "请输入新名字: " << endl;
			cin >> new_name;
			cout << "请输入岗位:" << endl;
			cout << "1 普通职工" << endl;
			cout << "2 经理" << endl;
			cout << "3 老板" << endl;
			cin >> new_deptid;
			Worker* worker = NULL;
			switch (new_deptid)
			{
			case 1:
				worker = new Employee(new_id, new_name, new_deptid);
				break;
			case 2:
				worker = new Manager(new_id, new_name, new_deptid);
				break;
			case 3:
				worker = new Boss(new_id, new_name, new_deptid);
				break;
			default:
				break;
			}
			//更改数据到数组中
			this->m_emparray[ret] = worker;
			cout << "修改成功" << endl;
			//保存到文件中
			this->save();
		}
		else
		{
			cout << "修改失败,查无此人" << endl;
		}
	}
	system("pause");
	system("cls");
}

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)//按照职工号查找
		{
			int id;
			cout << "请输入你想查找的职工编号: " << endl;
			cin >> id;
			int ret = IsExist(id);
			if (ret != -1)
			{
				cout << "查找成功,该职工的信息如下:" << endl;
				this->m_emparray[ret]->ShowInfo();
			}
			else
			{
				cout << "查找失败,查无此人" << endl;
			}
		}
		else if (select == 2)
		{
			string name;
			cout << "请输入你想查找的职工姓名:" << endl;
			cin >> name;
			bool flag = false;//查找到的标志
			for (int i = 0; i < this->m_empnum; i++)
			{
				if (m_emparray[i]->m_name == name)
				{
					cout << "查找成功,职工编号为" << m_emparray[i]->m_id << "号的信息如下:" << endl;
					flag = true;
					this->m_emparray[i]->ShowInfo();
				}
			}
			if (flag == false)
			{
				//查无此人
				cout << "查找失败,查无此人" << endl;
			}
		}
		else
		{
			cout << "输入选项有误" << endl;
		}
	}
	system("pause");
	system("cls");
}

void WorkManager::SortEmp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空" << endl;
		system("pause");
		system("cls");
	}
	else
	{
		//分布排序
		cout << "请选择排序方式:" << endl;
		cout << "1 按照职工号进行升序" << endl;
		cout << "2 按照职工号进行降序" << endl;
		int select = 0;
		cin >> select;
		for (int i = 0; i < m_empnum; i++)
		{
			int min_or_max = i;
			for (int j = i + 1; j < m_empnum; j++)
			{
				if (select == 1)//升序
				{
					if (m_emparray[min_or_max]->m_id > m_emparray[j]->m_id)
					{
						min_or_max = j;
					}
				}
				else//降序
				{
					if (m_emparray[min_or_max]->m_id < m_emparray[j]->m_id)
					{
						min_or_max = j;
					}
				}
			}
			if (i != min_or_max)
			{
				Worker* temp = m_emparray[i];
				m_emparray[i] = m_emparray[min_or_max];
				m_emparray[min_or_max] = temp;
			}
		}
		cout << "排序成功,排序后的结果:" << endl;
		this->save();
		this->ShowEmp();
	}
}

void WorkManager::CleanFile()
{
	cout << "确定清空文件?" << endl;
	cout << "1 确定" << endl;
	cout << "2 返回" << endl;
	int select = 0;
	cin >> select;
	if (select == 1)
	{
		//打开模式:ios::trunc如果存在则删除文件并重新创建
		ofstream ofs(FILENAME, ios::trunc);
		ofs.close();
		if (this->m_emparray != NULL)
		{
			for (int i = 0; i < this->m_empnum; i++)
			{
				if (this->m_emparray[i] != NULL)
				{
					delete this->m_emparray[i];
					this->m_emparray[i] = NULL;
				}
			}
			this->m_empnum = 0;
			delete[] this->m_emparray;
			this->m_emparray = NULL;
			this->m_FileIsEmpty = true;
		}
		cout << "清空成功" << endl;
	}
	system("pause");
	system("cls");
}

WorkManager::~WorkManager()
{
	if (this->m_emparray != NULL)
	{
		for (int i = 0; i < this->m_empnum; i++)
		{
			if (this->m_emparray[i] != NULL)
			{
				delete this->m_emparray[i];
				this->m_emparray[i] = NULL;
			}
		}
		this->m_empnum = 0;
		delete[] this->m_emparray;
		this->m_emparray = NULL;
		this->m_FileIsEmpty = true;
	}
}

03 总结

本项目对于老司机来说很简单,但对初学者来说还是有点难度的。由于本人能力有限,里面可能出现纰漏,欢迎大家在评论区友好交流,希望这篇博客能帮到你。
我已经把源码上传GitHub,欢迎下载。
链接:link(文件名为:基于多态的职工管理系统)

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值