网络知识 娱乐 C++实战之基于多态的文件交互型职工管理系统的实现

C++实战之基于多态的文件交互型职工管理系统的实现

随遇而安才是面对生活的态度

✨写在前面

        书接上文,上次刚讲完C++文件基础,那么趁热打铁直接开始实战。基于多态的职工管理系统难点就在于多态的实现以及文件交互的方法,由于牵扯的类和功能比较多,本篇博客采取分文件编写的方式来实现该系统。同时这也是我这个专栏的最后一篇博客,整整24篇,用来学习和复习真的是非常方便和高效。

       ✨✨ 感兴趣的同学可以订阅一下我的这个《C++入门》专栏喔~✨✨


✨目录

系统需求

效果展示 

分文件编写

布局

思路

含注释的各文件内容

所有头文件

所有源文件

✨总结 


系统需求

        职工管理系统可以用来管理公司内所有员工的信息,本篇博客主要利用C++来实现一个基于多态的职工管理系统。公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职责。管理系统中需要实现的功能如下:

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

效果展示 

刚打开程序时

增加职工功能

自动生成文件

显示功能

删除功能

修改功能

查找功能

有按职工号和名字查找两种

职工号查找

名字查找

按职工号排序

升序排序

降序排序

清空并退出

文件数据被清空:

分文件编写

包含布局和思路两块内容

布局

         worker.h头文件用来存放Worker类的声明,对应的worker.cpp源文件就是相关函数的实现,而boss、manager、employee、workerManager等头文件和对应cpp文件都是一样的,下面会有具体意义讲解。最后的职工管理系统.cpp就是对以上文件内容的调用了,综合下来完成职工管理。

思路

        Worker类是三种职工的基类,包含职工号,职工姓名和职工部门编号三种属性以及展示员工信息和得到岗位信息的纯虚函数。Boss、Manager、Employee三个类是其派生类,重写纯虚函数,使三个类的展示信息函数具有不同的表达。WorkerManager类含有所有的管理系统功能并能够存放三种职工的父类指针以及完成文件交互,是核心的一个类。

含注释的各文件内容

        源码内容,含有注释清晰知道函数的功能;

        注意头文件是功能声明,源文件是功能具体实现

所有头文件

worker.h

#pragma once//防止引入文件重复
#include
using namespace std;
class Worker
{
public:
	int id;//职工号
	string name;//职工姓名
	int dId;//部门编号
	virtual void showInfo() = 0;//展示职工信息
	virtual string getDegree() = 0;//得到职工岗位信息
};

boss.h

#pragma once
#include"worker.h"//用到Worker类就引入
class Boss :public Worker//Boss继承Worker类
{
public:
	Boss(int id, string name, int dId);//构造函数声明
	void showInfo();//重写的声明
	string getDegree();//同上
};

manager.h

#pragma once
#include"worker.h"
class Manager :public Worker
{
public:
	Manager(int id, string name, int dId);
	void showInfo();
	string getDegree();
};

employee.h

#pragma once
#include"worker.h"
class Employee :public Worker
{
public:
	Employee(int id,string name,int dId);
	void showInfo();
	string getDegree();
};
//老板经理员工类的头文件格式一样,只给一个注释

workerManager.h

#pragma once
#include
#include//引入文件流
#include"manager.h"
#include"worker.h"
#include"employee.h"
#include"boss.h"
#define FileName "employ.txt"//宏定义文件路径
using namespace std;
class WorkerManager
{
public:
	int _Num;//职工数
	Worker** arrayList;//职工数组指针,arratList数组中存放Worker类的指针,实现多态的重点
	bool fileEmpty;//文件是否为空的标志
	WorkerManager();//构造函数声明,用于属性初始化
	void addEmploy();//添加职工
	void showMenu();//展示菜单功能
	void exitSystem();//退出程序功能
	void saveFile();//保存文件功能
	int get_empNum();//得到初始化职工人数功能
	void init_emp();//初始化系统功能
	void visionemploy();//显示职工功能
	int existNo(int id);//按照职工号查找功能
	int existName(string name);//按照名字查找功能
	void findemploy();//查找职工功能,会调用上面的按职工号或者名字查找的功能
	void modifyemploy();//修改职工信息功能
	void deleteEmploy();//删除职工功能
	void sortemploy();//按职工号排序功能
	void destoryemploy();//清空文件数据功能
	~WorkerManager();//析构,用来释放开辟在堆区的数组
};

所有源文件

employee.cpp

#include"employee.h"
Employee::Employee(int id,string name,int dId)//构造函数的实现
{
	this->id = id;
	this->name = name;
	this->dId = dId;
}
void Employee::showInfo()//显示信息的函数实现
{
	cout << "职工编号:" <id
		<< "t职工姓名:" <name << "t岗位:"<getDegree()
		<<"t岗位职责:完成经理交代的任务"<<endl;
}
string Employee::getDegree()//得到岗位信息的函数实现
{
	return "员工";
}

manager.cpp

#include"manager.h"
Manager::Manager(int id, string name, int dId)
{
	this->id = id;
	this->name = name;
	this->dId = dId;
}
void Manager::showInfo()
{
	cout << "职工编号:" <id
		<< "t职工姓名:" <name << "t岗位:" <getDegree()
		<< "t岗位职责:上接老板,下发任务给员工" << endl;
}
string Manager::getDegree()
{
	return "经理";
}

boss.cpp

#include"boss.h"
Boss::Boss(int id, string name, int dId)
{
	this->id = id;
	this->name = name;
	this->dId = dId;
}
void Boss::showInfo()
{
	cout << "职工编号:" <id
		<< "t职工姓名:" <name << "t岗位:" <getDegree()
		<< "t岗位职责:有主导权,负责管理员工和经理" << endl;
}
string Boss::getDegree()
{
	return "老板";
}

workerManager.cpp

#include"workerManager.h"
//构造函数,完成文件的职工管理系统的初始化
WorkerManager::WorkerManager()
{
	//初始化失败
	ifstream ifs(FileName, ios::in);
	if (!ifs.is_open())
	{
		cout << "文件不存在" <_Num = 0;
		this->arrayList = NULL;
		this->fileEmpty = true;
		return;
	}
	char ch=' ';//用来判断文件是否为空
	if ((ifs>>ch).eof())
	{
		cout << "文件存在,但是不存在数据" <_Num = 0;
		this->arrayList = NULL;
		this->fileEmpty = true;
		return;
	}
	//初始化成功
	int size = this->get_empNum();
	cout << "职工人数为:" << size <_Num = size;
	//arrayList是存放指针的数组名,先new一个,创建空间
	this->arrayList = new Worker * [this->_Num];
	//调用初始化函数将文件信息作为指针存放到arrayList数组中
	this->init_emp();
}
//菜单
void WorkerManager::showMenu()
{
	cout << "t******************************" << endl;
	cout << "t*****欢迎使用职工管理系统*****" << endl;
	cout << "t*******0-退出管理程序*********" << endl;
	cout << "t*******1-增加职工信息*********" << endl;
	cout << "t*******2-显示职工信息*********" << endl;
	cout << "t*******3-删除离职职工*********" << endl;
	cout << "t*******4-修改职工信息*********" << endl;
	cout << "t*******5-查找职工信息*********" << endl;
	cout << "t*******6-按照编号排序*********" << endl;
	cout << "t*******7-清空所有数据*********" << endl;
	cout << "t******************************" << endl;
}
//排序
void WorkerManager::sortemploy()
{
	cout << "选择排序方式" << endl;
	cout << "1、按职工号升序排序" << endl;
	cout << "2、按职工号降序排序" <> choice;
	switch (choice)
	{
	case 1:
	{
		for (int i = 0; i _Num - 1; i++)
			for (int j = 0; j _Num - i - 1; j++)
			{
				if (this->arrayList[j]->id > this->arrayList[j + 1]->id)
				{
					Worker* worker = NULL;
					worker = this->arrayList[j];
					this->arrayList[j] = this->arrayList[j+1];
					this->arrayList[j + 1] = worker;
				}
			}
		this->saveFile();
		system("pause"); system("cls");
		break;
	}
	case 2:
	{
		for (int i = 0; i _Num - 1; i++)
			for (int j = 0; j _Num - i - 1; j++)
			{
				if (this->arrayList[j+1]->id > this->arrayList[j]->id)
				{
					Worker* worker = NULL;
					worker = this->arrayList[j];
					this->arrayList[j] = this->arrayList[j + 1];
					this->arrayList[j + 1] = worker;
				}
			}
		this->saveFile();
		system("pause"); system("cls");
		break;
	}
	default:
		break;
	}
	
}
//退出程序
void WorkerManager::exitSystem()
{
	cout << "退出程序成功,欢迎下次使用" << endl;
	system("pause");
	exit(0);
}
//添加新职工
void WorkerManager::addEmploy()
{
	int addCount = 0;
	cout <> addCount;
	while (addCount <= 0)
	{
		cout << "数据错误,请重写输入!" << endl;
		cout <> addCount;
	}
	int newSize= this->_Num + addCount;
	Worker**newArray = new  Worker* [newSize];
	if (this->arrayList != NULL)
	{
		for (int i = 0; i _Num; i++)
		{
			newArray[i] = this->arrayList[i];
		}
	}
	for (int i = 0; i < addCount; i++)
	{
		int id; string name; int dId;
		cout <> id;
		cout <> name;
		cout << "输入岗  位为:" << endl;
		cout << "***1--员工--2--经理--3--老板***" <> dId;
		Worker* worker = NULL;
		switch (dId)
		{
		case  1:worker = new Employee(id, name, dId); break;
		case  2:worker = new Manager(id, name, dId); break;
		case  3:worker = new Boss(id, name, dId); break;
		default:break;
		}
		newArray[this->_Num + i] = worker;
	}
	delete []this->arrayList;
	this->arrayList = newArray;
	this->_Num = newSize;
	this->fileEmpty = false;
	cout << "添加" << addCount << "个新职工成功" <saveFile();
	system("pause"); system("cls");
}
//保存文件
void WorkerManager::saveFile()
{
	ofstream ofs;
	ofs.open(FileName,ios::out);
	for (int i = 0; i _Num; i++)
	{
		ofs <arrayList[i]->id << " "
		    <arrayList[i]->name << " "
		    <arrayList[i]->dId << endl;
	}
	cout << "写入文件成功!" <> id && ifs >> name && ifs >> dId)
	{
		num++;
	}
	return num;
	ifs.close();
}
//初始化函数
void WorkerManager::init_emp()
{
	ifstream ifs(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);
		}
		this->arrayList[index] = worker;
		index++;
	}
	ifs.close();
}
//显示职工信息
void WorkerManager::visionemploy()
{
	if (fileEmpty)
	{
		cout << "文件不存在或者文件为空!" << endl;
	}
	else
	{
		for (int i = 0; i _Num; i++)
		{
			this->arrayList[i]->showInfo();
		}
	}
	system("pause"); system("cls");
}
//按职工号查找
int WorkerManager::existNo(int id)
{
	for (int i = 0; i _Num; i++)
	{
		if (arrayList[i]->id == id)
		{
			return i;
		}
	}
	return -1;
}
//按姓名查找
int WorkerManager::existName(string name)
{
	for (int i = 0; i _Num; i++)
	{
		if (arrayList[i]->name == name)
			return i;
	}
	return -1;
}
//查找职工功能
void WorkerManager::findemploy()
{
	int choose = 0;
	cout << "1、按职工号查找" << endl;
	cout << "2、按姓  名查找" <> choose;
	switch (choose)
	{
	case 1:
	{
		int id = 0;
		cout <> id;
		int v = this->existNo(id);
		if (v != -1)
		{
			cout << "查找结果为:" <arrayList[v]->showInfo();
		}
		else {
			cout << "查无此人" << endl;
		}
		system("pause"); system("cls");
		break;
	}
	case 2:
	{
		string name;
		cout <> name;
		int v = this->existName(name);
		if (v != -1)
		{
			cout << "查找结果为:" <arrayList[v]->showInfo();
		}
		else {
			cout << "查无此人" << endl;
		}
		system("pause"); system("cls");
		break;
	}
	default:
		break;
	}
}
//修改职工信息功能
void WorkerManager::modifyemploy()
{
	int id = 0;
	cout <> id;
	int v = this->existNo(id);
	if (v == -1)
	{
		cout << "查无此人" << endl;
	}
	else {
		int id; string name; int dId;
		cout <> id;
		cout <> name;
		cout << "输入岗  位为:" << endl;
		cout << "***1--员工--2--经理--3--老板***" <> dId;
		Worker* worker = NULL;
		switch (dId)
		{
		case  1:worker = new Employee(id, name, dId); break;
		case  2:worker = new Manager(id, name, dId); break;
		case  3:worker = new Boss(id, name, dId); break;
		default:break;
		}
		this->arrayList[v] = worker;
		this->saveFile();
	}
	system("pause"); system("cls");
}
//删除职工
void WorkerManager::deleteEmploy()
{
	int id = 0;
	cout <> id;
	int v = this->existNo(id);
	if (v == -1)
	{
		cout << "查无此人" << endl;
	}
	else {
		for (int i = v; i _Num; i++)
		{
			this->arrayList[i] = this->arrayList[i + 1];
		}
		this->_Num--;
	}
	cout << "删除成功!" <saveFile();
	system("pause"); system("cls");
}
//清空文件数据
void WorkerManager::destoryemploy()
{
	delete this->arrayList;
	this->arrayList = NULL;
	cout << "确认删除所有信息吗?" << endl;
	cout << "选择 1 确认删除" << endl;
	cout << "选择 2 撤销操作" <> choice;
	switch (choice)
	{
	case 1:
	{
		ofstream ofs(FileName, ios::trunc);
		ofs << " ";
		cout << "删除成功,请按0退出程序" << endl; 
		system("pause"); system("cls");
		break;
	}
	case 2:cout << "删除未保存,请重新打开程序" <arrayList != NULL)
	{
		delete[] this->arrayList;
		this->arrayList = NULL;
	}
}

职工管理系统.cpp

#include
#include"worker.h"
#include"employee.h"
#include"manager.h"
#include"boss.h"
#include"workerManager.h"
using namespace std;
int main(void)
{
    //创建职工管理类指针,用来调用其他函数
	WorkerManager *workerManager=new WorkerManager();
	int choice = 0;
	while (1)
	{
		workerManager->showMenu();//调用菜单功能
		cout <> choice;
		switch (choice)
		{
			case 0:workerManager->exitSystem(); //退出
			case 1:workerManager->addEmploy(); break;//添加
			case 2:workerManager->visionemploy(); break;//显示
			case 3:workerManager->deleteEmploy(); break;//删除
			case 4:workerManager->modifyemploy(); break;//修改
			case 5:workerManager->findemploy(); break;//查找
			case 6:workerManager->sortemploy(); break;//排序
			case 7:workerManager->destoryemploy(); break;//清空
		}
	}
	system("pause");
	return 0;
}

总结 

        这里的代码直接可以复制后粘贴到Visual Stduio中使用,具体使用方法就是按照分文件编写里的布局创建的头文件和对应的源文件,然后将代码分别对应赋值粘贴运行即可。那么到现在这个专栏就结束了,心里也是比较舒坦,希望大家多多支持喔~