职工管理系统

         这两天跟着B站黑马程序员敲完了C++的职工管理系统,又学到了很多东西,对类和对象、继承、多态以及一些基础语法知识有了进一步的理解。我跟着敲下来,发现最难的部分不是各个功能的实现问题,而是除了功能之外,你需要为实现这些功能所做的一些铺垫。譬如把某一部分单独封装成函数、初始化一些内容等等。不过我想这是因为我接触C++时间不长的原因,多接触代码应该可以有所改善。其中有一点是我认为最难想到的就是初始化数据,我本来想怎么样才能让这个函数每次运行一开始就能执行,把文本中的数据搬到程序的数组里,没想到竟然忘记了构造函数,构造函数总是最先运行,所以我应该把一些一开始就要准备好的东西放在构造函数里。而析构函数最后执行,所以我可以放入一些释放空间的语句,来防止内存的泄露。

还整理了一些问题:

1、类内重新定义了构造函数和析构函数时,类外需要重新定义
2、不要重复包含有同样内容的头文件
3、父类的纯虚函数子类需要重写,注意一定要完全一致,否则子类为抽象类无法实例化
4、读取文件时中文字出现乱码:将文件另存为,在右下角位置将编码改为ANSI编码。

下面按照编程思路贴下代码:

一、创建一个包含职工信息的类(worker.h),稍后会分别用不同职工的类来继承这个类

'''cplusplus

#pragma once
#include<iostream>
#include<string>

using namespace std;

class Worker {
public:

	//显示个人信息
	virtual void showInfo() =0;

	//获取岗位名称
	virtual string getDtName() =0 ;

	//职工编号
	int m_Id;

	//姓名
	string m_Name;

	//部门
	int m_DtId;
};

 二、构建不同职工的类(employee.h、manager.h、boss.h),这里面需要对父类的纯虚函数进行的重定义(注意保持完全一致,virtual可写可不写),否则这些子类会称为抽象类,无法实例化具体的员工。

#pragma once
#include<iostream>
#include"worker.h"

using namespace std;

class Employee :public Worker {
public:

	Employee(int id, string name,int did);

	//显示个人信息
	void showInfo() ;

	//获取岗位名称
	string getDtName() ;

	//~Employee();
};

#pragma once
#include<iostream>
#include<string>
#include"worker.h"


//经理类
class Manager :public Worker {
public:
	Manager(int id, string name, int did);

	//显示个人信息
	void showInfo();

	//获取岗位名称
	string getDtName();
};

 

#pragma once
#include<iostream>
#include<string>
#include"worker.h"


//老板
class Boss :public Worker {
public:
	Boss(int id, string name, int did);

	//显示个人信息
	void showInfo();

	//获取岗位名称
	string getDtName();
};

三、完成三种员工的头文件中具体函数的定义(employee.cpp、manager.cpp、boss.cpp)

 这三部分代码都很类似,但要注意的是需要包含各自的头文件以及函数需要包含作用域。

#include<iostream>
#include<string>
#include"employee.h"
using namespace std;

//构造函数
Employee::Employee(int id,string name,int did) {
	this->m_Id=id;
	this->m_Name=name;
	this->m_DtId=did;
}

//显示个人信息
void Employee::showInfo() {
	cout << "职工编号:" << this->m_Id
		<< "\t职工姓名:" << this->m_Name
		<< "\t岗位:" << this->getDtName()
		<< "\t岗位职责:完成经理交给的任务。\n";
}

//获取岗位名称
string  Employee::getDtName() {
	return string("员工");
}
#include<iostream>
#include<string>
#include"manager.h"
using namespace std;


Manager::Manager(int id, string name, int did) {
	this->m_Id = id;
	this->m_Name = name;
	this->m_DtId = did;
}

//显示个人信息
void Manager::showInfo() {
	cout << "职工编号:" << this->m_Id
		<< "\t职工姓名:" << this->m_Name
		<< "\t岗位:" << this->getDtName()
		<< "\t岗位职责:完成老板交给的任务,并下发任务给员工。\n";
}

//获取岗位名称
string Manager::getDtName() {
	return string("经理");
}
#include<iostream>
#include<string>
#include"boss.h"
using namespace std;


Boss::Boss(int id, string name, int did) {
	this->m_Id = id;
	this->m_Name = name;
	this->m_DtId = did;
}

//显示个人信息
void Boss::showInfo() {
	cout << "职工编号:" << this->m_Id
		<< "\t职工姓名:" << this->m_Name
		<< "\t岗位:" << this->getDtName()
		<< "\t岗位职责:管理公司所有事务。\n";
}

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

四、实现具体功能的定义(workermanager.h、workermanager.cpp),前者是函数定义,后者是函数实现

//函数定义

#pragma once//防止头文件重复包含
#include<iostream>//包含输入输出流头文件
//#include"workerManager.cpp"
using namespace std;//使用标准命名空间
#include"worker.h"
#include<fstream>
#define FILENAME "workerfile.txt"

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

	void ExitSystem();
	void ShowMenu();


	//记录职工人数
	int m_EmpNum;

	//职工数组指针
	Worker ** m_EmpArray;

	//添加职工功能
	void Add_Emp();

	//保存文件
	void save();

	//判断文件是否为空
	bool m_FileIsEmpty;

	//统计人数
	int get_EmpNum();

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

	//显示员工
	void show_Emp();

	//删除职工
	void del_Emp();

	//判断职工是否存在
	int IsExit(int id);

	//判断职工姓名是否存在
	int IsnameExit(string name);

	//修改职工
	void mod_Emp();

	//查找职工
	void find_Emp();

	//排序
	void sort_Emp();

	//清空文件
	void clean_Emp();

	//析构函数
	~WorkManager();


 };
///写函数体

#include"workermanager.h"
#include<iostream>
#include<string.h>
#include"boss.h"
#include"employee.h"
#include"manager.h"


using namespace std;


WorkManager::WorkManager() {

	//文件不存在
	ifstream ifs;
	//读文件
	ifs.open(FILENAME, ios::in);

	if (!ifs.is_open() ){
		//cout<<"文件不存在!"<<endl;
		//初始化属性
		//初始化人数为0
		this->m_EmpNum = 0;
		//初始化数组为空
		this->m_EmpArray = NULL;
		//初始化文件是否为空
		this->m_FileIsEmpty = true;
		ifs.close();
		return;
	}
	//文件存在但数据为空
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
		//cout << "文件为空!" << endl;
		//初始化人数为0
		this->m_EmpNum = 0;
		//初始化数组为空
		this->m_EmpArray = NULL;
		//初始化文件是否为空
		this->m_FileIsEmpty = true;
		ifs.close();
		return;
	}

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

	//开辟空间
	this->m_EmpArray = new Worker * [this->m_EmpNum];
	//将文件中数据存到数组中
	this->init_Emp();

	/*for (int i = 0; i < this->m_EmpNum; i++) {
		cout << "职工编号:" << this->m_EmpArray[i]->m_Id<<" ";
		cout << "姓名:" << this->m_EmpArray[i]->m_Name<<" ";
		cout << "部门编号:" << this->m_EmpArray[i]->m_DtId << endl;;
	}*/
}

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

//函数实现
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::Add_Emp() {
	cout << "请输入添加的职工数量:" << endl;

	//记录添加职工数量
	int addNum = 0;
	cin >> addNum;

	if (addNum > 0) {
		
		//计算添加新空间大小
		//新空间大小等于原来空间加添加人数
		int newSize = this->m_EmpNum + addNum;

		//开辟新空间
		Worker** newSpace=new Worker* [newSize];

		//将原来空间下数据拷贝到新空间下
		if (this->m_EmpNum != NULL) {
			for (int i = 0; i < this->m_EmpNum; i++) {
				newSpace[i] = this->m_EmpArray[i];
			}
		}
		
		//将职员写入文件

		//批量添加新数据
		for (int i = 0; i < addNum; i++) {
			int id;//职工编号
			string name;//职工姓名
			int dptnum;//职工岗位编号

			//判断编号是否已经存在,若存在则重新输入
			while (true){
				cout << "请输入第" << i + 1 << "个职工编号:" << endl;
				cin >> id;
				int ret = this->IsExit(id);
				if (ret != -1) {
					cout << "该员工编号已存在!" << endl;
				}
				else {
					break;
				}
			}
			
			cout << "请输入第" << i + 1 << "个职工姓名:" << endl;
			cin >> name;
			cout << "请输入选择该职工岗位:" << endl;
			cout << "1.普通职工" << endl;
			cout << "2.经理" << endl;
			cout << "3.老板" << endl;
			cin >> dptnum;

			Worker* worker = NULL;
			switch (dptnum) {
			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_EmpNum+i] = worker;
			
			
		}
		//用newSpace代替了m_EmpArray,需要释放原有的空间
		delete[] this->m_EmpArray;

		//更新新空间指向
		this->m_EmpArray = newSpace;

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

		//更新职工信息不为空
		this->m_FileIsEmpty = false;

		//提示添加成功
		cout << "成功添加" << addNum << "名新职工" << 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 < m_EmpNum; i++) {
		ofs << this->m_EmpArray[i]->m_Id << "  "
			<< this->m_EmpArray[i]->m_Name << "  "
			<< this->m_EmpArray[i]->m_DtId<<endl;
			
	}
	ofs.close(); //关闭文件
}


//统计文件中人数
int WorkManager::get_EmpNum() {

	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	int id;
	string name;
	int dId;
	int num = 0;
	while (ifs>>id&&ifs>>name&&ifs>>dId) {
		num++;
	}
	ifs.close();
	return num;
}

//初始化职工
void WorkManager::init_Emp() {

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

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

	while (ifs >> id && ifs >> name && ifs >> DtId) {
		
		Worker* worker = NULL;
		
		//普通职工
		if (DtId == 1) {
			worker = new Employee(id, name, DtId);
		}
		//经理
		else if (DtId == 2) {
			worker = new Manager(id, name, DtId);
		}
		//老板
		else  {
			worker = new Boss(id, name, DtId);
		}
		this->m_EmpArray[index] = worker;
		index++;
	}
	ifs.close();
}


//显示员工
void WorkManager::show_Emp() {
	if (this->m_EmpNum == 0) {
		cout << "尚未添加员工信息!" << endl;
	}
	else {
		for (int i = 0; i < this->m_EmpNum; i++) {
			//利用多态调用程序接口哦
			this->m_EmpArray[i]->showInfo();

			/*cout << "职工编号:" << this->m_EmpArray[i]->m_Id << " "
				<< "姓名:" << this->m_EmpArray[i]->m_Name << " ";
			if (this->m_EmpArray[i]->m_DtId == 1) {
				cout<< "职位:普通员工" << endl;
			}
			else if (this->m_EmpArray[i]->m_DtId == 2) {
				cout << "职位:经理" << endl;
			}
			else {
				cout << "职位:老板" << endl;
			}			*/	
		}
	}
	system("pause");
	system("cls");
}

//判断职工是否存在,存在返回职工所在数组位置
int WorkManager::IsExit(int id) {
	int index = -1;

	for (int i = 0; i < this->m_EmpNum;i++) {
		if (this->m_EmpArray[i]->m_Id == id) {
			//找到职工
			index = i;
			break;
		}
	}
	return index;
}

判断职工是否存在,存在返回职工所在数组位置
//int WorkManager::IsnameExit(string name) {
//	int index = -1;
//
//	for (int i = 0; i < this->m_EmpNum; i++) {
//		if (this->m_EmpArray[i]->m_Name == name) {
//			//找到职工
//			index = i;
//			break;
//		}
//	}
//	return index;
//}

//删除职工
void WorkManager::del_Emp() {

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

		int index = this->IsExit(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--;
			//将数据同步到文件中
			this->save();

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

	}
}


//修改职工
void WorkManager::mod_Emp() {
	if (this->m_FileIsEmpty) {
		cout << "文件不存在或记录为空" << endl;
	}
	else {
		cout << "请输入您要修改的职工的编号:" << endl;
		int id;
		cin >> id;
		int ret = this->IsExit(id);
		if (ret == -1) {
			cout << "未找到该员工,修改失败!" << endl;
		}
		else {
			
			//先删除这个员工信息
			delete this->m_EmpArray[ret];

			//再添加新的员工信息
			int id;
			string name;
			int select;
			cout << "请输入新职工编号:" << endl;
			cin >> id;
			cout << "请输入新姓名:" << endl;
			cin >> name;
			cout << "请输入选择该职工岗位:" << endl;
			cout << "1.普通职工" << endl;
			cout << "2.经理" << endl;
			cout << "3.老板" << endl;
			cin >> select;

			//将员工信息放入数组
			Worker* worker = NULL;
			switch (select) {
			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_EmpArray[ret] = worker;
			cout << "员工信息修改成功!" << endl;

			//保存到文件中
			this->save();

		}
	}

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

//查找职工
void WorkManager::find_Emp() {
	if (this->m_FileIsEmpty) {
		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 = this->IsExit(id);
			if (ret == -1) {
				cout << "未找到该员工!" << endl;
			}
			else {
				cout << "查找成功!该职工信息如下:" << endl;
				this->m_EmpArray[ret]->showInfo();

				/*cout << "编号:" << this->m_EmpArray[ret]->m_Id <<"   ";
				cout << "姓名:" << this->m_EmpArray[ret]->m_Name <<"   ";
				switch (this->m_EmpArray[ret]->m_DtId) {
				case 1:
					cout << "岗位:员工" << "   "
						<< "岗位职责:完成经理交给的任务。";
					break;
				case 2:
					cout << "岗位:经理" << "   "
						<< "岗位职责:完成老板交给的任务,并下发任务给员工。";
					break;
				case 3:
					cout << "岗位:老板" << "   "
						<< "岗位职责:管理公司所有事务。";
					break;
				default:
					break;*/
				}
				
			}
		//按照姓名查找
		else if (select == 2) {
			
			string name;
			cout << "请输入您要查找的员工的姓名:" << endl;
			cin >> name;
			bool flag = false;
			for (int i = 0; i < this->m_EmpNum; i++) {
				
				if (this->m_EmpArray[i]->m_Name == name) {
					cout << "查找成功,职工编号为:" 
						<< this->m_EmpArray[i]->m_Id
						<< "的职工信息如下:" << endl;

					this->m_EmpArray[i]->showInfo();
					flag = true;
				}
			}
			if (!flag) {
				cout << "您的输入有误,查无此人!" << endl;
			}
		}
		}	
	system("pause");
	system("cls");
}
	

//排序:用冒泡实现
void WorkManager::sort_Emp() {
	if (this->m_FileIsEmpty) {
		cout << "文件不存在或记录为空" << endl;
	}
	else {
		cout << "请选择您要排序的方式:" << endl;
		cout << "1.从小到大" << endl;
		cout << "2.从大到小" << endl;
		int select;
		cin >> select;

		//从小到大排序
		if (select == 1) {
			for (int i = 0; i < this->m_EmpNum; i++) {
				for (int j = 0; j < this->m_EmpNum-i-1; j++) {
					if (this->m_EmpArray[j]->m_Id > this->m_EmpArray[j + 1]->m_Id) {
						Worker* worker = NULL;
						worker = this->m_EmpArray[j];
						this->m_EmpArray[j] = this->m_EmpArray[j + 1];
						this->m_EmpArray[j + 1] = worker;
					}
				}
			}
			this->save();
			cout << "排序成功!" << endl;
		}

		//从大到小排序
		else if (select == 2){
			for (int i = 0; i < this->m_EmpNum; i++) {
				for (int j = 0; j < this->m_EmpNum - i - 1; j++) {
					if (this->m_EmpArray[j]->m_Id < this->m_EmpArray[j + 1]->m_Id) {
						Worker* temp = NULL;
						temp = this->m_EmpArray[j];
						this->m_EmpArray[j] = this->m_EmpArray[j + 1];
						this->m_EmpArray[j + 1] = temp;
					}
				}
			}
			this->save();
			cout << "排序成功!" << endl;
		}
	}
	system("pause");
	system("cls");
}

排序:用选择实现
//void WorkManager::sort_Emp() {
//	if (this->m_FileIsEmpty) {
//		cout << "文件不存在或记录为空" << endl;
//	}
//	else {
//		cout << "请选择您要排序的方式:" << endl;
//		cout << "1.从小到大" << endl;
//		cout << "2.从大到小" << endl;
//		int select;
//		cin >> select;
//
//		//从小到大排序
//		if (select == 1) {
//			int min=0;
//			for (int i=1; i < this->m_EmpNum; i++) {
//				if (this->m_EmpArray[i]->m_Id < this->m_EmpArray[min]->m_Id) {
//
//				}
//			}
//		}
//	}
//}


//清空文件
void WorkManager::clean_Emp() {
	if (this->m_FileIsEmpty) {
		cout << "文件不存在或记录为空" << endl;
	}
	else {
		int select;
		cout << "请再次确认是否清空文件:" << endl;
		cout << "1.确定" << endl;
		cout << "2.取消" << endl;
		cin >> select;
		if (select == 1) {
			/*this->m_EmpNum = 0;
			cout << "文件已清空!" << endl;
			this->save();*/

			//清空文件
			ofstream ofs(FILENAME, ios::trunc);//trunc删除文件后重新创建文件
			ofs.close();

			if (this->m_EmpNum != NULL) {

				//删除堆区每个职工对象
				for (int i = 0; i < this->m_EmpNum; i++) {
					delete this->m_EmpArray[i];
					this->m_EmpArray[i] = NULL;
				}

				//删除堆区数组指针
				delete[] this->m_EmpArray;
				this->m_EmpArray = NULL;
				this->m_EmpNum = 0;
				this->m_FileIsEmpty = true;
			}
			cout << "清空成功" << endl;
		}	
		else if (select == 2) {
		}
	}
	system("pause");
	system("cls");
}


//手动释放内存
WorkManager::~WorkManager() {
	if (this->m_EmpArray != NULL) {
		delete[] this->m_EmpArray;
		this->m_EmpArray = NULL;
	}
}

五、主函数

#include"workermanager.h"
#include<iostream>
#include<string.h>
#include"worker.h"
#include"employee.h"
#include"manager.h"
#include"boss.h"

using namespace std;

int main()
{
	WorkManager wm;
	int select = 0;
	
	while (true){
		wm.ShowMenu();
		cout << "请输入您的选择:" << endl;
		cin >> select;

		switch (select)
		{
		case 0:   //退出系统
			wm.ExitSystem();
			break;
		case 1:   //增加职工
			wm.Add_Emp();
			break;
		case 2:   //显示职工
			wm.show_Emp(); 
			break;
		case 3:	   //删除职工
			wm.del_Emp();
			break; 
		case 4:    //修改职工
			wm.mod_Emp();
			break;
		case 5:    //查找职工
			wm.find_Emp();
			break;
		case 6:    //排序职工
			wm.sort_Emp();
			break;
		case 7:    //清空文档
			wm.clean_Emp();
			break;
		default:
			system("cls");//清屏操作
			break;
		}
		
	}
	
	system("pause");
	return 0;
}

代码不是完全按照这个顺序来敲的,肯定都是交叉的编写。其中还是有很多地方自己不太熟练,理解不到位,还有很长的路要走,希望通过这样记录的方式,方便自己以后学习。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值