C++:基于多态的职工管理系统
主要功能
1、在系统中增加员工信息,包括(员工编号,员工姓名,员工岗位,岗位职责),在本地生成相应文件储存数据。
2、将文件中的数据读取出来并作显示。
3、按照员工编号删除指定员工的相关数据。
4、按照员工编号修改指定员工数据。
5、按照员工编号或员工姓名查找指定员工信息并显示。
6、将员工按照员工编号进行升序或降序排列。
7、清空文件中所有的员工数据。
增加功能
1、在新增员工选项下,保证了员工ID的唯一性,当输入重复ID号时,有错误提示,并提示用户重新输入。
2、在清除所有文件数据选项下,当用户输入其他选项时,具有错误提示,并提示用户重新输入。
Bug解决
在新增员工选项下,在选择岗位时,用户输入错误选项导致的程序崩溃
具体代码
main.cpp
#include <iostream>
using namespace std;
#include "workermanage.h"
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"
int main(){
WorkerManager wm;
int choice = 0;
while(true)
{
wm.ShowMenu();
cout << "Please input your choice" << endl;
cin >> choice;
switch(choice)
{
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_File();
break;
default:
system("cls");
break;
}
}
return 0;
}
父类 worker类的创建
由于使用到多态技术,我们把父类 worker 作为抽象类,并创建纯虚函数,并在之后的子类中重写与继承,故只有头文件
worker.h
#pragma once //防止头文件重复包含
#include <iostream>
using namespace std;
#include<string>
class Worker{
public:
virtual void showInfo() = 0; //纯虚函数构造
virtual string getDeptName() = 0; //纯虚函数构造
int m_Id;
string m_Name;
int m_DeptId;
};
employee子类,继承自父类worker
employee.h
#pragma once
#include<iostream>
#include <string>
using namespace std;
#include "worker.h"
class Employee :public Worker{
public:
Employee(int id, string name, int dId);
virtual void showInfo();
virtual string getDeptName();
};
employee.cpp
#include "employee.h"
Employee::Employee(int id, string name, int dId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = dId;
}
void Employee::showInfo()
{
cout << "Employee ID:" << this->m_Id
<<"\t Employee name:" << this->m_Name
<<"\t Post:" << this->getDeptName()
<<"\t Responsibility: Complete the tasks assigned by the mangaer" << endl;
}
string Employee::getDeptName()
{
return string("Stuff");
}
manager子类,继承自父类worker
manager.h
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include "worker.h"
class Manager :public Worker
{
public:
Manager(int id, string name, int dId);
virtual void showInfo();
virtual string getDeptName();
};
manager.cpp
#include "manager.h"
Manager::Manager(int id, string name, int dId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = dId;
}
void Manager::showInfo()
{
cout << "Employee ID:" << this->m_Id
<<"\t Employee name:" << this->m_Name
<<"\t Post:" << this->getDeptName()
<<"\t Responsibility: Complete the tasks assigned by the boss" << endl;
}
string Manager::getDeptName()
{
return string("Manager");
}
boss子类,继承自父类worker
boss.h
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include "worker.h"
class Boss: public Worker{
public:
Boss(int id, string name, int dId);
virtual void showInfo();
virtual string getDeptName();
};
boss.cpp
#include "boss.h"
Boss::Boss(int id, string name, int dId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = dId;
}
void Boss::showInfo()
{
cout << "Employee ID:" << this->m_Id
<<"\t Employee name:" << this->m_Name
<<"\t Post:" << this->getDeptName()
<<"\t Responsibility: Assign tasks to employees" << endl;
}
string Boss::getDeptName()
{
return string("Boss");
}
workermanager
实现主要功能的核心代码
workermanager.h
#pragma once //防止头文件重复包含
#include <iostream>
using namespace std;
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"
#include <fstream>
#define FileName "Empfile.txt"
class WorkerManager{
public:
WorkerManager();
void ShowMenu();
void ExitSystem();
int m_EmpNum;
Worker ** m_EmpArray;
void Add_Emp();
void save();
bool FileisEmpty;
int get_EmpNum();
void init_Emp();
void show_Emp();
void del_Emp();
int EmpisExist(int id);
void mod_Emp();
void Find_Emp();
void Sort_Emp();
void Clean_File();
~WorkerManager();
};
workermanager.cpp
#include "workermanage.h"
WorkerManager::WorkerManager()
{
ifstream ifs;
ifs.open(FileName, ios::in);
if (!ifs.is_open())
{
//cout << "File is not exit" << endl;
this->m_EmpNum = 0;
this->m_EmpArray = NULL;
this->FileisEmpty = true;
ifs.close();
return;
}
char ch;
ifs >> ch;
if(ifs.eof())
{
//cout << "File is empty !" << endl;
this->m_EmpNum = 0;
this->m_EmpArray = NULL;
this->FileisEmpty = true;
ifs.close();
return;
}
int num = this->get_EmpNum();
//cout << "The number of Employee is " << num << endl;
this->m_EmpNum = num;
this->FileisEmpty = false;
//开辟空间
this->m_EmpArray = new Worker *[this->m_EmpNum];
this->init_Emp();
// for (int i = 0; i < this->m_EmpNum; i++)
// {
// cout << "Employee number is :" << this->m_EmpArray[i]->m_Id
// << " Employee name is :" << this->m_EmpArray[i]->m_Name
// << " Employee department is :" << this->m_EmpArray[i]->m_DeptId << endl;
// }
}
void WorkerManager::ShowMenu()
{
cout << "------------------------------------------" << endl;
cout << "Welcome to the Workforce Management System" << endl;
cout << "-------- 0->Exit Management System -------" << endl;
cout << "-------- 1->Add New Employee -------------" << endl;
cout << "-------- 2->Display Employee Information -" << endl;
cout << "-------- 3->Delete Employee --------------" << endl;
cout << "-------- 4->Edit Employee Information ----" << endl;
cout << "-------- 5->Find Employee Information ----" << endl;
cout << "-------- 6->Sort Employee ----------------" << endl;
cout << "-------- 7->Clear All Recoder ------------" << endl;
cout << "------------------------------------------" << endl;
cout << endl;
}
void WorkerManager::ExitSystem()
{
cout << "See you!!" << endl;
system("pause");
exit(0);
}
void WorkerManager::Add_Emp()
{
cout << "Please enter the number of employees:" << endl;
int addNum = 0;
cin >> addNum;
if (addNum > 0)
{
//计算新的空间的大小
int newSize = this->m_EmpNum + addNum;
Worker ** newSpace = new Worker*[newSize];
//将原空间内存下的内容放到新空间下
if(this->m_EmpArray != 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 dId;
cout << "Please enter the " << i + 1 << " new employee number" << endl;
cin >> id;
bool flag = true;
if (this->FileisEmpty)
{
flag = false;
}
int NowNum = this->m_EmpNum + i;
int Num_count = 0;
while(flag)
{
Num_count = 0;
for (int j = 0; j < NowNum; j++)
{
if(newSpace[j]->m_Id == id)
{
cout << "Id is existed, please enter again" << endl;
cout << "Please enter the " << i + 1 << " new employee number" << endl;
cin >> id;
break;
}
else
{
Num_count ++;
if(Num_count == NowNum)
{
flag = false;
}
}
}
}
Num_count = 0;
cout << "Please enter the name of the new employee" << endl;
cin >> name;
cout << "please enter the dId of the new employee" << endl;
cout << "1->Stuff" << endl;
cout << "2->Manager" << endl;
cout << "3->Boss" << endl;
cin >> dId;
Worker *worker = NULL;
while(1)
{
if(dId == 1 || dId == 2 || dId ==3)
{
switch (dId)
{
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;
}
break;
}
else{
cout <<"Enter error!!! Please enter again" << endl;
cin >> dId;
}
}
newSpace[this->m_EmpNum + i] = worker;
NowNum ++;
}
//释放原有空间
delete[] this->m_EmpArray;
//更改新空间的指向
this->m_EmpArray = newSpace;
//更新新的个数
this->m_EmpNum = newSize;
this->FileisEmpty = false;
cout << addNum << " employees were added successfully" << endl;
this->save();
}
else{
cout << "Input error!" << endl;
}
system("pause");
system("cls");
}
void WorkerManager::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 WorkerManager::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 WorkerManager::init_Emp()
{
ifstream ifs;
ifs.open(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 if(dId == 3)
{
worker = new Boss(id ,name, dId);
}
else{
cout << "dId is error!" << endl;
}
this->m_EmpArray[index] = worker;
index++;
}
ifs.close();
}
void WorkerManager::show_Emp()
{
if(this->FileisEmpty)
{
cout << "File is Empty or do not exist!" << endl;
}
else{
for(int i = 0; i < this->m_EmpNum; i++)
{
this->m_EmpArray[i]->showInfo();
}
}
system("pause");
system("cls");
}
void WorkerManager::del_Emp()
{
if(this->FileisEmpty)
{
cout << "File is not exist or is empty" << endl;
}
else{
cout << "Plese enter the employee number to be deleted:" << endl;
int id;
cin >> id;
int index = this->EmpisExist(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 << "Emlpoyee delete succsee!" << endl;
}
else
{
cout << "Error!! This employee is not exist !" << endl;
}
}
system("pause");
system("cls");
}
int WorkerManager::EmpisExist(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;
}
void WorkerManager::mod_Emp()
{
if(this->FileisEmpty)
{
cout << "File is not exist or is empty" << endl;
}
else{
cout << "Please enter the emlpoyee ID to be modified" << endl;
int id;
cin >> id;
int index = this->EmpisExist(id);
if(index != -1)
{
delete this->m_EmpArray[index];
int newid = 0;
string newname = "";
int newdId = 0;
cout <<"Finded the " << id << " emlpoyee" << endl;
cout << "Please eneter the new ID:" << endl;
cin >> newid;
cout << "Please enter the new name" << endl;
cin >> newname;
cout <<"Please seclect a new post:" << endl;
cout <<"1->Stuff" << endl;
cout <<"2->Manager" << endl;
cout <<"3->Boss" << endl;
cin >> newdId;
Worker *worker = NULL;
switch (newdId)
{
case 1:
worker = new Employee(newid, newname, newdId);
break;
case 2:
worker = new Manager(newid, newname, newdId);
break;
case 3:
worker = new Boss(newid, newname, newdId);
break;
default:
break;
}
this->m_EmpArray[index] = worker;
cout << "Modify successfully" << endl;
this->save();
}
else
{
cout << "Error!! This employee is not exist !" << endl;
}
}
system("pause");
system("cls");
}
void WorkerManager::Find_Emp()
{
if (this->FileisEmpty)
{
cout << "File is not exit or is empty" << endl;
}
else{
cout << "Please enter the search method" << endl;
cout << "1->Search by number"<< endl;
cout << "2->Search by name" << endl;
int select = 0;
cin >> select;
if(select == 1)
{
cout << "Please enter the employee number you want to find" << endl;
int id;
cin >> id;
int index = this->EmpisExist(id);
if(index != -1)
{
cout << "Find haa been done" << endl;
this->m_EmpArray[index]->showInfo();
}
else{
cout << "Error!! This employee is not exist !" << endl;
}
}
else if(select == 2)
{
cout << "Please enter the name you want to find" << endl;
string name;
cin >> name;
bool flag = false;
for (int i = 0; i < this->m_EmpNum; i++)
{
if(this->m_EmpArray[i]->m_Name == name)
{
cout << "Find successfully" << endl;
cout << "The employee's id is" << this->m_EmpArray[i]->m_Id << endl;
flag = true;
this->m_EmpArray[i]->showInfo();
}
}
if(flag == false)
{
cout << "Error!! This employee is not exist !" << endl;
}
}
else{
cout << "Input Error!!" << endl;
}
}
system("pause");
system("cls");
}
void WorkerManager::Sort_Emp()
{
if(this->FileisEmpty)
{
cout << "File is not exist or is empty" << endl;
system("pause");
system("cls");
}
else{
cout << "Please select a sort method" << endl;
cout << "1->Ascending sort by ID" << endl;
cout << "2->Desdending sort by ID" << endl;
int select = 0;
cin >> select;
for(int i = 0; i < this->m_EmpNum; i++)
{
int MinOrMax = i;
for (int j = i + 1; j < this->m_EmpNum; j++)
{
if(select == 1)
{
if(this->m_EmpArray[MinOrMax]->m_Id > this->m_EmpArray[j]->m_Id)
{
MinOrMax = j;
}
}
else if(select == 2)
{
if(this->m_EmpArray[MinOrMax]->m_Id < this->m_EmpArray[j]->m_Id)
{
MinOrMax = j;
}
}
else{
cout << "Input error!!!" << endl;
}
}
if(i != MinOrMax)
{
Worker * temp = this->m_EmpArray[i];
this->m_EmpArray[i] = this->m_EmpArray[MinOrMax];
this->m_EmpArray[MinOrMax] = temp;
}
}
cout << "Sort successfully, the sorted result is :" << endl;
this->save();
this->show_Emp();
}
}
void WorkerManager::Clean_File()
{
cout << "Warning: The file will be completely cleared!" << endl;
cout << "1->Continue : clear all data" << endl;
cout << "2->Exit : return to menu" << endl;
int select = 0;
cin >> select;
while(1)
{
if(select == 1 || select == 2)
{
break;
}
else
{
cout << "Enter error!!! Please enter again" << endl;
cin >> select;
}
}
if(select==1)
{
ofstream ofs;
ofs.open(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];
}
}
delete [] this->m_EmpArray;
this->m_EmpArray = NULL;
this->m_EmpNum = 0;
this->FileisEmpty = true;
}
cout << "Clear successfully" << endl;
}
system("pause");
system("cls");
}
WorkerManager::~WorkerManager()
{
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];
}
}
delete[] this->m_EmpArray;
this->m_EmpArray = NULL;
}
}
增加功能代码说明
1、保证员工ID的唯一性
思路描述
利用while循环对用户输入的ID进行判定,如果ID与文件中的ID重复,做while循环并对用户进行相应的提示。
bool flag = true;
if (this->FileisEmpty) //在文件为空时增加员工会导致程序进入死循环
{ //利用this->FileisEmpty判断文件是否为空
flag = false; //如果文件为空则意味着不会有ID重复,直接跳过while循环进行后续输入
}
int NowNum = this->m_EmpNum + i; //将现存数据大小与已经添加的数据相加进行更新,防止ID重复判定时忽略最新添加的员工ID
int Num_count = 0; //保证输入ID与现存ID全部进行比较,比较完成后,如果没有重复退出while循环
while(flag)
{
Num_count = 0; //记得置零
for (int j = 0; j < NowNum; j++)
{
if(newSpace[j]->m_Id == id)
{
cout << "Id is existed, please enter again" << endl;
cout << "Please enter the " << i + 1 << " new employee number" << endl;
cin >> id;
break;
}
else
{
Num_count ++; //同步进行更新
if(Num_count == NowNum)
{
flag = false;
}
}
}
}
Num_count = 0; //记得置零,保证下一次的ID重复判定
2、在清除所有文件数据选项下,当用户输入其他选项时,具有错误提示,并提示用户重新输入。
void WorkerManager::Clean_File()
{
cout << "Warning: The file will be completely cleared!" << endl;
cout << "1->Continue : clear all data" << endl;
cout << "2->Exit : return to menu" << endl;
int select = 0;
cin >> select;
while(1) //进行while循环,当用户输入为 1 或 2时退出循环,否则会进行错误提示,并让用户重新输入
{
if(select == 1 || select == 2)
{
break;
}
else
{
cout << "Enter error!!! Please enter again" << endl;
cin >> select;
}
}
if(select==1)
{
ofstream ofs;
ofs.open(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];
}
}
delete [] this->m_EmpArray;
this->m_EmpArray = NULL;
this->m_EmpNum = 0;
this->FileisEmpty = true;
}
cout << "Clear successfully" << endl;
}
system("pause");
system("cls");
}
3、解决岗位输入错误导致的程序崩溃
while(1) //进行while循环,只有当用户输入为 1 或 2 或 3时退出循环,否则会进行错误提示,并让用户重新输入
{
if(dId == 1 || dId == 2 || dId ==3)
{
switch (dId)
{
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;
}
break;
}
else{
cout <<"Enter error!!! Please enter again" << endl;
cin >> dId;
}
}