職工管理系統(tǒng)
1. 管理系統(tǒng)需求
職工管理系統(tǒng)可以用來管理公司內(nèi)所有員工的信息,利用C++來實現(xiàn)一個基于多態(tài)的職工管理系統(tǒng)
公司中職工分為三類:普通員工、經(jīng)理、老板,顯示信息時,需要顯示職工編號、職工姓名、職工崗位、以及職責(zé)
-
普通員工職責(zé):完成經(jīng)理交給的任務(wù)
-
經(jīng)理職責(zé):完成老板交給的任務(wù),并下發(fā)任務(wù)給員工
-
老板職責(zé):管理公司所有事務(wù)
管理系統(tǒng)中需要實現(xiàn)的功能如下:
- 退出管理程序:退出當(dāng)前管理系統(tǒng)
- 增加職工信息:實現(xiàn)批量添加職工功能,將信息錄入到文件中,職工信息為:職工編號、姓名、部門編號
- 顯示職工信息:顯示公司內(nèi)部所有職工的信息
- 刪除離職職工:按照編號刪除指定的職工
- 修改職工信息:按照編號修改職工個人信息
- 查找職工信息:按照職工的編號或者職工的姓名進行查找相關(guān)的人員信息
- 按照編號排序:按照職工編號,進行排序,排序規(guī)則由用戶指定
- 清空所有文檔:清空文件中記錄的所有職工信息 (清空前需要再次確認,防止誤刪)
2. 創(chuàng)建管理類
管理類負責(zé)的內(nèi)容如下:
- 與用戶的溝通菜單界面
- 對職工增刪改查的操作
- 與文件的讀寫交互
2.1 創(chuàng)建文件
在頭文件和源文件的文件夾下分別創(chuàng)建 workerManager.h
和 workerManager.cpp
文件
2.2 頭文件實現(xiàn)
在 workerManager.h
中設(shè)計管理類
代碼如下:
#pragma once
#include <iostream>
class WorkerManager
{
public:
WorkerManager();
~WorkerManager();
};
2.3 源文件實現(xiàn)
在 workerManager.cpp
中將構(gòu)造和析構(gòu)函數(shù)空實現(xiàn)補全
#include "workerManager.h"
WorkerManager::WorkerManager()
{
}
WorkerManager::~WorkerManager()
{
}
至此職工管理類以創(chuàng)建完畢
3. 菜單功能
3.1 添加成員函數(shù)
在管理類 workerManager.h
中添加成員函數(shù) void Show_Menu();
#pragma once
#include <iostream>
class WorkerManager
{
public:
WorkerManager();
void showMenu();
~WorkerManager();
};
3.2 菜單功能實現(xiàn)
在管理類 workerManager.h
中添加成員函數(shù) void Show_Menu();
void WorkerManager::showMenu()
{
std::cout << "********************************************" << std::endl;
std::cout << "********* 歡迎使用職工管理系統(tǒng)! **********" << std::endl;
std::cout << "************* 0.退出管理程序 *************" << std::endl;
std::cout << "************* 1.增加職工信息 *************" << std::endl;
std::cout << "************* 2.顯示職工信息 *************" << std::endl;
std::cout << "************* 3.刪除離職職工 *************" << std::endl;
std::cout << "************* 4.修改職工信息 *************" << std::endl;
std::cout << "************* 5.查找職工信息 *************" << std::endl;
std::cout << "************* 6.按照編號排序 *************" << std::endl;
std::cout << "************* 7.清空所有文檔 *************" << std::endl;
std::cout << "********************************************" << std::endl;
std::cout << std::endl;
}
3.3 測試菜單功能
main.cpp
文件中中測試菜單功能
#include <iostream>
#include "workerManager.h"
int main()
{
WorkerManager wm;
wm.showMenu();
return 0;
}

4. 退出功能
4.1 提供功能接口
在main函數(shù)中提供分支選擇,提供每個功能接口
int main()
{
WorkerManager wm;
int choise = 0;
while (true)
{
wm.showMenu();
std::cout << "請輸入你的選擇: " << std::endl;
std::cin >> choise;
switch (choise)
{
case 0: //退出系統(tǒng)
break;
case 1: //添加職工
break;
case 2: //顯示職工
break;
case 3: //刪除職工
break;
case 4: //修改職工
break;
case 5: //查找職工
break;
case 6: //排序職工
break;
case 7: //清空文件
break;
default:
system("cls");
break;
}
}
return 0;
}
4.2 實現(xiàn)退出功能
在 workerManager.h
中提供退出系統(tǒng)的成員函數(shù) void exitSystem();
在 workerManager.cpp
中提供具體的功能實現(xiàn)
void WorkerManager::exitSystem()
{
cout << "歡迎下次使用" << endl;
system("pause");
exit(0);
}
4.3 測試功能
在main函數(shù)分支 0 選項中,調(diào)用退出程序的接口

5. 創(chuàng)建職工類
5.1 創(chuàng)建職工抽象類
職工的分類為:普通員工、經(jīng)理、老板
將三種職工抽象到一個類 (worker) 中,利用多態(tài)管理不同職工種類
職工的屬性為:職工編號、職工姓名、職工所在部門編號
職工的行為為:崗位職責(zé)信息描述,獲取崗位名稱
頭文件文件夾下 創(chuàng)建文件 worker.h
文件并且添加如下代碼:
#pragma once
#include <iostream>
class Worker
{
public:
int m_Id;
std::string m_Name;
int m_DeptId;
virtual void showInfo() = 0;
virtual std::string getDeptName() = 0;
};
5.2 創(chuàng)建普通員工類
普通員工類繼承職工抽象類,并重寫父類中純虛函數(shù)
在頭文件和源文件的文件夾下分別創(chuàng)建 employee.h
和 employee.cpp
文件
employee.h
中代碼如下:
#pragma once
#include <iostream>
#include "worker.h"
class Employee :public Worker
{
public:
Employee(int id, std::string name, int deptId);
void showInfo();
std::string getDeptName();
};
employee.cpp
中代碼如下:
#include "employee.h"
Employee::Employee(int id, std::string name, int deptId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = deptId;
}
void Employee::showInfo()
{
std::cout
<< "職工編號: " << this->m_Id
<< " \t職工姓名: " << this->m_Name
<< " \t崗位: " << this->getDeptName()
<< " \t崗位職責(zé): 完成經(jīng)理交給的任務(wù)" << std::endl;
}
std::string Employee::getDeptName()
{
return std::string("普通員工");
}
5.3 創(chuàng)建經(jīng)理類
經(jīng)理類繼承職工抽象類,并重寫父類中純虛函數(shù),和普通員工類似
在頭文件和源文件的文件夾下分別創(chuàng)建 manager.h
和 manager.cpp
文件
manager.h
中代碼如下:
#pragma once
#include <iostream>
#include "worker.h"
class Manager :public Worker
{
public:
Manager(int id, std::string name, int deptId);
void showInfo();
std::string getDeptName();
};
manager.cpp
中代碼如下:
#include "manager.h"
Manager::Manager(int id, std::string name, int deptId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = deptId;
}
void Manager::showInfo()
{
std::cout
<< "職工編號: " << this->m_Id
<< " \t職工姓名: " << this->m_Name
<< " \t崗位: " << this->getDeptName()
<< " \t崗位職責(zé): 完成老板交給的任務(wù),并下發(fā)任務(wù)給員工" << std::endl;
}
std::string Manager::getDeptName()
{
return std::string("經(jīng)理");
}
5.4 創(chuàng)建老板類
老板類繼承職工抽象類,并重寫父類中純虛函數(shù),和普通員工類似
在頭文件和源文件的文件夾下分別創(chuàng)建 boss.h
和 boss.cpp
文件
boss.h
中代碼如下:
#pragma once
#include <iostream>
#include "worker.h"
class Boss :public Worker
{
public:
Boss(int id, std::string name, int deptId);
void showInfo();
std::string getDeptName();
};
boss.cpp
中代碼如下:
#include "boss.h"
Boss::Boss(int id, std::string name, int deptId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = deptId;
}
void Boss::showInfo()
{
std::cout
<< "職工編號: " << this->m_Id
<< " \t職工姓名: " << this->m_Name
<< " \t崗位: " << this->getDeptName()
<< " \t崗位職責(zé): 管理公司所有事務(wù)" << std::endl;
}
std::string Boss::getDeptName()
{
return std::string("老板");
}
5.5 測試多態(tài)
main.cpp
中添加測試函數(shù),并且運行能夠產(chǎn)生多態(tài)
測試代碼如下:
void test1()
{
Worker* worker = new Employee(1, "張三", 1);
worker->showInfo();
delete worker;
worker = new Manager(2, "李四", 2);
worker->showInfo();
delete worker;
worker = new Boss(3, "王五", 3);
worker->showInfo();
delete worker;
}
6. 添加職工
功能描述:批量添加職工,并且保存到文件中
6.1 功能分析
分析:
用戶在批量創(chuàng)建時,可能會創(chuàng)建不同種類的職工
如果想將所有不同種類的員工都放入到一個數(shù)組中,可以將所有員工的指針維護到一個數(shù)組里
如果想在程序中維護這個不定長度的數(shù)組,可以將數(shù)組創(chuàng)建到堆區(qū),并利用 Worker **
的指針維護

6.2 功能實現(xiàn)
在 WorkerManager.h
頭文件中添加成員屬性代碼:
//職工人數(shù)
int m_EmpNum;
//職工數(shù)組
Worker** m_EmpArray;
在 WorkerManager
構(gòu)造函數(shù)中初始化屬性
WorkerManager::WorkerManager()
{
this->m_EmpNum = 0;
this->m_EmpArray = NULL;
}
在 WorkerManager.h
中添加成員函數(shù)
void add_Emp();
WorkerManager.cpp
中實現(xiàn)該函數(shù)
void WorkerManager::add_Emp()
{
std::cout << "請輸入添加職工的數(shù)量: " << std::endl;
int addNum = 0;
std::cin >> addNum;
if (addNum > 0)
{
int newSize = this->m_EmpNum + addNum;
Worker** newSpace = new Worker* [newSize];
//假如文件內(nèi)不為空,申請數(shù)組將文件中的內(nèi)容讀到內(nèi)存中操作
if (this->m_EmpArray != NULL)
{
//把原有的數(shù)組都移動到新開辟的內(nèi)存中
for (int i = 0; i < this->m_EmpNum; i++)
{
newSpace[i] = this->m_EmpArray[i];
}
}
//假如文件為空或不為空,則直接開辟后添加
for (int i = 0; i < addNum; i++)
{
int id;
std::string name;
int deptId;
std::cout << "請輸入第[" << i + 1 << "]個職工編號: ";
std::cin >> id;
std::cout << "請輸入第[" << i + 1 << "]個職工姓名: ";
std::cin >> name;
std::cout << "請選擇該職工的崗位" << std::endl;
std::cout << "1.普通員工" << std::endl;
std::cout << "2.經(jīng)理" << std::endl;
std::cout << "3.老板" << std::endl;
std::cin >> deptId;
Worker* newWorker = NULL;
switch (deptId)
{
case 1:
newWorker = new Employee(id, name, 1);
break;
case 2:
newWorker = new Manager(id, name, 2);
break;
case 3:
newWorker = new Boss(id, name, 3);
break;
default:
break;
}
newSpace[this->m_EmpNum + i] = newWorker;
}
delete[] this->m_EmpArray;
this->m_EmpArray = newSpace;
this->m_EmpNum = newSize;
this->m_FileIsEmpty = false;
std::cout << "成功添加" << addNum << "人" << std::endl;
this->save();
}
else
{
std::cout << "輸入有誤,請重新輸入!" << std::endl;
}
system("pause");
system("cls");
}
7. 文件交互——寫文件
功能描述:對文件進行讀寫
在上一個添加功能中,我們只是將所有的數(shù)據(jù)添加到了內(nèi)存中,一旦程序結(jié)束就無法保存了
因此文件管理類中需要一個與文件進行交互的功能,對于文件進行讀寫操作
7.1 設(shè)定文件路徑
首先我們將文件路徑,在 workerManager.h
中添加宏常量,并且包含頭文件 fstream
#include <fstream>
#define FILENAME "empFile.txt"
7.2 成員函數(shù)聲明
在 workerManager.h
中類里添加成員函數(shù) void save()
//保存文件
void save();
7.3 保存文件功能實現(xiàn)
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();
}
7.4 保存文件功能測試
在添加職工功能中添加成功后添加保存文件函數(shù)
8. 文件交互——讀文件
功能描述:將文件中的內(nèi)容讀取到程序中
雖然我們實現(xiàn)了添加職工后保存到文件的操作,但是每次開始運行程序,并沒有將文件中數(shù)據(jù)讀取到程序中
而我們的程序功能中還有清空文件的需求
因此構(gòu)造函數(shù)初始化數(shù)據(jù)的情況分為三種
- 第一次使用,文件未創(chuàng)建
- 文件存在,但是數(shù)據(jù)被用戶清空
- 文件存在,并且保存職工的所有數(shù)據(jù)
8.1 文件未創(chuàng)建
在 workerManager.h
中添加新的成員屬性 m_FileIsEmpty
標(biāo)志文件是否為空
//標(biāo)志文件是否為空
bool m_FileIsEmpty;
修改 WorkerManager.cpp
中構(gòu)造函數(shù)代碼
WorkerManager::WorkerManager()
{
//文件不存在
std::ifstream ifs(FILENAME, std::ios::in);
if (!ifs.is_open())
{
std::cout << "文件不存在" << std::endl;
this->m_EmpNum = 0;
this->m_EmpArray = NULL;
this->m_FileIsEmpty = true;
ifs.close();
return;
}
}
刪除文件后,測試文件不存在時初始化數(shù)據(jù)功能
8.2 文件存在且數(shù)據(jù)為空
在 workerManager.cpp
中的構(gòu)造函數(shù)追加代碼:
//文件存在,但沒有內(nèi)容
char buf;
ifs >> buf;
//只讀文件里的第一個位置,看看是否是空的
if (ifs.eof())
{
std::cout << "文件為空" << std::endl;
this->m_EmpNum = 0;
this->m_EmpArray = NULL;
this->m_FileIsEmpty = true;
ifs.close();
return;
}
8.3 文件存在且保存職工數(shù)據(jù)
8.3.1 獲取記錄的職工人數(shù)
在 workerManager.h
中添加成員函數(shù) int get_EmpNum();
//統(tǒng)計人數(shù)
int get_EmpNum();
workerManager.cpp
中實現(xiàn)
int WorkerManager::get_EmpNum()
{
std::ifstream ifs(FILENAME, std::ios::in);
int id;
std::string name;
int deptId;
int count = 0;
//這種方法會使文件內(nèi)容為空的情況下仍然返回1,造成緩沖區(qū)溢出
/*
char buf[1024] = { 0 };
while (ifs.getline(buf, sizeof(buf)))
{
num++;
}
*/
while (ifs >> id && ifs >> name && ifs >> deptId)
{
count++;
}
ifs.close();
return count;
}
在 workerManager.cpp
構(gòu)造函數(shù)中繼續(xù)追加代碼:
int num = this->get_EmpNum();
cout << "職工個數(shù)為:" << num << endl; //測試代碼
this->m_EmpNum = num; //更新成員屬性
8.3.2 初始化數(shù)組
根據(jù)職工的數(shù)據(jù)以及職工數(shù)據(jù),初始化 workerManager
中的 Worker ** m_EmpArray
指針
在 workerManager.h
中添加成員函數(shù) void init_Emp();
//初始化員工
void init_Emp();
在 workerManager.cpp
中實現(xiàn)
void WorkerManager::init_Emp()
{
std::ifstream ifs(FILENAME, std::ios::in);
int id;
std::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->m_EmpArray[index] = worker;
index++;
}
ifs.close();
}
在 workerManager.cpp
構(gòu)造函數(shù)中追加代碼
//根據(jù)職工數(shù)創(chuàng)建數(shù)組
this->m_EmpArray = new Worker *[this->m_EmpNum];
//初始化職工
init_Emp();
//測試代碼
for (int i = 0; i < m_EmpNum; i++)
{
cout << "職工號: " << this->m_EmpArray[i]->m_Id
<< " 職工姓名: " << this->m_EmpArray[i]->m_Name
<< " 部門編號: " << this->m_EmpArray[i]->m_DeptId << endl;
}
9. 顯示職工
功能描述:顯示當(dāng)前所有職工信息
9.1 顯示職工函數(shù)聲明
在 workerManager.h
中添加成員函數(shù) void Show_Emp();
//顯示職工
void show_Emp();
9.2 顯示職工函數(shù)實現(xiàn)
在 workerManager.cpp
中實現(xiàn)成員函數(shù) void Show_Emp();
//顯示職工
void WorkerManager::show_Emp()
{
if (this->m_FileIsEmpty)
{
cout << "文件不存在或記錄為空!" << endl;
}
else
{
for (int i = 0; i < m_EmpNum; i++)
{
//利用多態(tài)調(diào)用接口
this->m_EmpArray[i]->showInfo();
}
}
system("pause");
system("cls");
}
10. 刪除職工
10.1 刪除職工函數(shù)聲明
在 workerManager.h
中添加成員函數(shù) void del_Emp();
//修改職工
void del_Emp();
10.2 職工是否存在函數(shù)聲明
很多功能都需要用到根據(jù)職工是否存在來進行操作如:刪除職工、修改職工、查找職工
因此添加該公告函數(shù),以便后續(xù)調(diào)用
在 workerManager.h
中添加成員函數(shù) int isExist(int id);
//按照職工編號判斷職工是否存在,若存在返回職工在數(shù)組中位置,不存在返回-1
int isExist(int id);
10.3 職工是否存在函數(shù)實現(xiàn)
在 workerManager.cpp
中實現(xiàn)成員函數(shù) int isExist(int id);
int WorkerManager::isExist(int id)
{
int count = -1;
for (int i = 0; i < this->m_EmpNum; i++)
{
if (this->m_EmpArray[i]->m_Id == id)
{
count = i;
break;
}
}
return count;
}
10.4 刪除職工函數(shù)實現(xiàn)
在 workerManager.cpp
中實現(xiàn)成員函數(shù) void Del_Emp();
void WorkerManager::del_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
}
else
{
int id = -1;
std::cout << "請輸入你要刪除的職工編號: ";
std::cin >> id;
int result = isExist(id);
if (result != -1)
{
for (int i = result; i < this->m_EmpNum - 1; i++)
{
this->m_EmpArray[i] = this->m_EmpArray[i + 1];
}
this->m_EmpNum--;
this->save();
std::cout << "刪除成功" << std::endl;
}
else
{
std::cout << "沒有找到職工編號為[" << id << "]的員工" << std::endl;
}
}
system("pause");
system("cls");
}
11. 修改職工
功能描述:能夠按照職工的編號對職工信息進行修改并保存
11.1 修改職工函數(shù)聲明
在 workerManager.h
中添加成員函數(shù) void mod_Emp();
//修改職工
void mod_Emp();
11.2 修改職工函數(shù)實現(xiàn)
在 workerManager.cpp
中實現(xiàn)成員函數(shù) void_mod_Emp();
void WorkerManager::mod_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
return;
}
int id = -1;
std::cout << "請輸入你要修改的職工編號: ";
std::cin >> id;
int result = isExist(id);
if (result != -1)
{
this->m_EmpArray[result]->showInfo();
int id;
std::string name;
int deptId;
std::cout << "請輸入修改的職工編號: ";
std::cin >> id;
std::cout << "請輸入修改的職工姓名: ";
std::cin >> name;
std::cout << "請選擇該職工的崗位" << std::endl;
std::cout << "1.普通員工" << std::endl;
std::cout << "2.經(jīng)理" << std::endl;
std::cout << "3.老板" << std::endl;
std::cin >> deptId;
Worker* modWorker = NULL;
switch (deptId)
{
case 1:
modWorker = new Employee(id, name, 1);
break;
case 2:
modWorker = new Manager(id, name, 2);
break;
case 3:
modWorker = new Boss(id, name, 3);
break;
default:
break;
}
this->m_EmpArray[result] = modWorker;
this->save();
std::cout << "修改成功,修改后的信息如下" << std::endl;
this->m_EmpArray[result]->showInfo();
}
else
{
std::cout << "沒有找到職工編號為[" << id << "]的員工" << std::endl;
}
system("pause");
system("cls");
}
為什么不能直接覆蓋?
沒有真正改變子類對象,假如數(shù)組中是這樣的

//直接操縱數(shù)組中存放的值
this->m_EmpArray[result].m_Id;
this->m_EmpArray[result].m_Name;
this->m_EmpArray[result].m_deptId;

類型沒有變化,那么你就擁有了這個類型的所有函數(shù)。試想一下,假如一位普通員工升職成為經(jīng)理了,但是它的類型仍然是Employee,而Manager中所有的權(quán)限他都沒有,所以直接覆蓋值是不對的

12. 查找職工
功能描述:提供兩種查找職工方式,一種按照職工編號,一種按照職工姓名
12.1 查找職工函數(shù)聲明
在 workerManager.h
中添加成員函數(shù) void find_Emp();
//查找職工
void find_Emp();
12.2 查找職工函數(shù)實現(xiàn)
在 workerManager.cpp
中實現(xiàn)成員函數(shù) void find_Emp();
void WorkerManager::find_Emp()
{
std::cout << "請輸入查找的方式:" << std::endl;
std::cout << "1.按員工編號查找" << std::endl;
std::cout << "2.按員工姓名查找" << std::endl;
int choise = 0;
std::cin >> choise;
if (choise == 1)
{
int id;
std::cout << "請輸入你要查找的員工編號: ";
std::cin >> id;
int result = isExist(id);
if (result != -1)
{
std::cout << "查找成功,員工信息如下:" << std::endl;
this->m_EmpArray[result]->showInfo();
}
else
{
std::cout << "沒有找到職工編號為[" << id << "]的員工" << std::endl;
}
}
else if (choise == 2)
{
std::string name;
std::cout << "請輸入你要查找的員工姓名: ";
std::cin >> name;
bool flag = false;
for (int i = 0; i < this->m_EmpNum; i++)
{
if (this->m_EmpArray[i]->m_Name == name)
{
std::cout << "查找成功,員工信息如下:" << std::endl;
this->m_EmpArray[i]->showInfo();
flag = true;
}
}
if (flag == false)
{
std::cout << "沒有找到職工姓名為[" << name << "]的員工" << std::endl;
}
}
else
{
std::cout << "輸入有誤,請重新輸入" << std::endl;
}
system("pause");
system("cls");
}
13. 職工排序
功能描述:按照職工編號進行排序,排序的順序由用戶指定
13.1 排序函數(shù)聲明
在 workerManager.h
中添加成員函數(shù) void sort_Emp();
//排序職工
void sort_Emp();
13.2 排序函數(shù)實現(xiàn)
在 workerManager.cpp
中實現(xiàn)成員函數(shù) void sort_Emp();
void WorkerManager::sort_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
system("pause");
system("cls");
}
else
{
std::cout << "請輸入排序的方式:" << std::endl;
std::cout << "1.按員工編號升序" << std::endl;
std::cout << "2.按員工編號降序" << std::endl;
int choise = 0;
std::cin >> choise;
//升序
for (int i = 0; i < this->m_EmpNum; i++)
{
int Min_Or_Max = i;
for (int j = i + 1; j < this->m_EmpNum; j++)
{
if (choise == 1)
{
//前一個大于后一個,就移動min指針
if (this->m_EmpArray[Min_Or_Max]->m_Id > this->m_EmpArray[j]->m_Id)
{
Min_Or_Max = j;
}
//前一個小于后一個,繼續(xù)往后比較
}
else if (choise == 2)
{
//前一個小于后一個,就移動max指針
if (this->m_EmpArray[Min_Or_Max]->m_Id < this->m_EmpArray[j]->m_Id)
{
Min_Or_Max = j;
}
//前一個大于后一個,繼續(xù)往后比較
}
}
//一輪比較后,如果標(biāo)記位置變了,交換位置
if (Min_Or_Max != i)
{
Worker* tempWorker = this->m_EmpArray[i];
this->m_EmpArray[i] = this->m_EmpArray[Min_Or_Max];
this->m_EmpArray[Min_Or_Max] = tempWorker;
}
}
this->save();
std::cout << "排序完成,排序后的結(jié)果如下:" << std::endl;
this->show_Emp();
}
}
該排序算法選用 選擇排序 難度不大,如果沒有算法基礎(chǔ)可以去看算法可視化動畫,沒有基礎(chǔ)的人看完一般在1個小時內(nèi)能夠?qū)懗鰜泶笾碌乃悸?/p>
14. 清空文件
功能描述:將文件中記錄數(shù)據(jù)清空
14.1 清空函數(shù)聲明
在 workerManager.h
中聲明函數(shù) void clean_File();
//清空文件
void clean_File();
14.2 清空函數(shù)實現(xiàn)
在 workerManager.cpp
中實現(xiàn)成員函數(shù) void clean_File();
void WorkerManager::clean_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
}
else
{
std::cout << "請確認是否需要清空?" << std::endl;
std::cout << "1.清空" << std::endl;
std::cout << "2.返回" << std::endl;
int choise = 0;
std::cin >> choise;
if (choise == 1)
{
std::ofstream ofs(FILENAME, std::ios::trunc);
ofs.close();
if (this->m_EmpArray != 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;
}
std::cout << "清空成功" << std::endl;
}
}
system("pause");
system("cls");
}
源代碼及文件結(jié)構(gòu)
├─頭文件
│ boss.h
│ employee.h
│ worker.h
│ workerManager.h
│
├─源文件
│ boss.cpp
│ employee.cpp
│ EmploySys.cpp
│ manager.cpp
│ workerManager.cpp
項目關(guān)系圖:

1. 員工類
1.1 員工抽象類 Worker — 基類
worker.h
#pragma once
#include <iostream>
class Worker
{
public:
int m_Id;
std::string m_Name;
int m_DeptId;
virtual void showInfo() = 0;
virtual std::string getDeptName() = 0;
};
1.2 普通員工類 Employee — 派生類
Employee.h
#pragma once
#include <iostream>
#include "worker.h"
class Employee :public Worker
{
public:
Employee(int id, std::string name, int deptId);
void showInfo();
std::string getDeptName();
};
Employee.cpp
#include "employee.h"
Employee::Employee(int id, std::string name, int deptId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = deptId;
}
void Employee::showInfo()
{
std::cout
<< "職工編號: " << this->m_Id
<< " \t職工姓名: " << this->m_Name
<< " \t崗位: " << this->getDeptName()
<< " \t崗位職責(zé): 完成經(jīng)理交給的任務(wù)" << std::endl;
}
std::string Employee::getDeptName()
{
return std::string("普通員工");
}
1.3 經(jīng)理類 Manager — 派生類
Manager.h
#pragma once
#include <iostream>
#include "worker.h"
class Manager :public Worker
{
public:
Manager(int id, std::string name, int deptId);
void showInfo();
std::string getDeptName();
};
Manager.cpp
#include "manager.h"
Manager::Manager(int id, std::string name, int deptId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = deptId;
}
void Manager::showInfo()
{
std::cout
<< "職工編號: " << this->m_Id
<< " \t職工姓名: " << this->m_Name
<< " \t崗位: " << this->getDeptName()
<< " \t崗位職責(zé): 完成老板交給的任務(wù),并下發(fā)任務(wù)給員工" << std::endl;
}
std::string Manager::getDeptName()
{
return std::string("經(jīng)理");
}
1.4 老板類 Boss — 派生類
Boss.h
#pragma once
#include <iostream>
#include "worker.h"
class Boss :public Worker
{
public:
Boss(int id, std::string name, int deptId);
void showInfo();
std::string getDeptName();
};
Boss.cpp
#include "boss.h"
Boss::Boss(int id, std::string name, int deptId)
{
this->m_Id = id;
this->m_Name = name;
this->m_DeptId = deptId;
}
void Boss::showInfo()
{
std::cout
<< "職工編號: " << this->m_Id
<< " \t職工姓名: " << this->m_Name
<< " \t崗位: " << this->getDeptName()
<< " \t崗位職責(zé): 管理公司所有事務(wù)" << std::endl;
}
std::string Boss::getDeptName()
{
return std::string("老板");
}
2. 員工管理類
該類用于聲明和實現(xiàn)主界面的所有操作
workerManager.h
#pragma once
#include <iostream>
#include <fstream>
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"
#define FILENAME "empFile.txt"
class WorkerManager
{
public:
int m_EmpNum;
Worker** m_EmpArray;
bool m_FileIsEmpty;
WorkerManager();
void showMenu();
void exitSystem();
void add_Emp();
void save();
int get_EmpNum();
void init_Emp();
void show_Emp();
int isExist(int id);
void del_Emp();
void mod_Emp();
void find_Emp();
void sort_Emp();
void clean_Emp();
~WorkerManager();
};
workerManager.cpp
#include "workerManager.h"
WorkerManager::WorkerManager()
{
//文件不存在
std::ifstream ifs(FILENAME, std::ios::in);
if (!ifs.is_open())
{
//std::cout << "文件不存在" << std::endl;
this->m_EmpNum = 0;
this->m_EmpArray = NULL;
this->m_FileIsEmpty = true;
ifs.close();
return;
}
//文件存在,但沒有內(nèi)容
char buf;
ifs >> buf;
//只讀文件里的第一個位置,看看是否是空的
if (ifs.eof())
{
//std::cout << "文件為空" << std::endl;
this->m_EmpNum = 0;
this->m_EmpArray = NULL;
this->m_FileIsEmpty = true;
ifs.close();
return;
}
//文件存在,并且記錄數(shù)據(jù)
int num = this->get_EmpNum();
this->m_EmpNum = num;
this->m_EmpArray = new Worker * [this->m_EmpNum];
this->init_Emp();
}
void WorkerManager::showMenu()
{
std::cout << "********************************************" << std::endl;
std::cout << "********* 歡迎使用職工管理系統(tǒng)! **********" << std::endl;
std::cout << "************* 0.退出管理程序 *************" << std::endl;
std::cout << "************* 1.增加職工信息 *************" << std::endl;
std::cout << "************* 2.顯示職工信息 *************" << std::endl;
std::cout << "************* 3.刪除離職職工 *************" << std::endl;
std::cout << "************* 4.修改職工信息 *************" << std::endl;
std::cout << "************* 5.查找職工信息 *************" << std::endl;
std::cout << "************* 6.按照編號排序 *************" << std::endl;
std::cout << "************* 7.清空所有文檔 *************" << std::endl;
std::cout << "********************************************" << std::endl;
std::cout << std::endl;
}
void WorkerManager::exitSystem()
{
std::cout << "歡迎下次使用" << std::endl;
exit(0);
}
void WorkerManager::add_Emp()
{
std::cout << "請輸入添加職工的數(shù)量: " << std::endl;
int addNum = 0;
std::cin >> addNum;
if (addNum > 0)
{
int newSize = this->m_EmpNum + addNum;
Worker** newSpace = new Worker * [newSize];
//假如文件內(nèi)不為空,申請數(shù)組將文件中的內(nèi)容讀到內(nèi)存中操作
if (this->m_EmpArray != NULL)
{
//把原有的數(shù)組都移動到新開辟的內(nèi)存中
for (int i = 0; i < this->m_EmpNum; i++)
{
newSpace[i] = this->m_EmpArray[i];
}
}
//假如文件為空或不為空,則直接開辟后添加
for (int i = 0; i < addNum; i++)
{
int id;
std::string name;
int deptId;
std::cout << "請輸入第[" << i + 1 << "]個職工編號: ";
std::cin >> id;
std::cout << "請輸入第[" << i + 1 << "]個職工姓名: ";
std::cin >> name;
std::cout << "請選擇該職工的崗位" << std::endl;
std::cout << "1.普通員工" << std::endl;
std::cout << "2.經(jīng)理" << std::endl;
std::cout << "3.老板" << std::endl;
std::cin >> deptId;
Worker* newWorker = NULL;
switch (deptId)
{
case 1:
newWorker = new Employee(id, name, 1);
break;
case 2:
newWorker = new Manager(id, name, 2);
break;
case 3:
newWorker = new Boss(id, name, 3);
break;
default:
break;
}
newSpace[this->m_EmpNum + i] = newWorker;
}
delete[] this->m_EmpArray;
this->m_EmpArray = newSpace;
this->m_EmpNum = newSize;
this->m_FileIsEmpty = false;
std::cout << "成功添加" << addNum << "人" << std::endl;
this->save();
}
else
{
std::cout << "輸入有誤,請重新輸入!" << std::endl;
}
system("pause");
system("cls");
}
void WorkerManager::save()
{
std::ofstream ofs(FILENAME, std::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 << std::endl;
}
ofs.close();
}
int WorkerManager::get_EmpNum()
{
std::ifstream ifs(FILENAME, std::ios::in);
int id;
std::string name;
int deptId;
int count = 0;
//這種方法會使文件內(nèi)容為空的情況下仍然返回1,造成緩沖區(qū)溢出
/*
char buf[1024] = { 0 };
while (ifs.getline(buf, sizeof(buf)))
{
num++;
}
*/
while (ifs >> id && ifs >> name && ifs >> deptId)
{
count++;
}
ifs.close();
return count;
}
void WorkerManager::init_Emp()
{
std::ifstream ifs(FILENAME, std::ios::in);
int id;
std::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->m_EmpArray[index] = worker;
index++;
}
ifs.close();
}
void WorkerManager::show_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
}
else
{
for (int i = 0; i < m_EmpNum; i++)
{
this->m_EmpArray[i]->showInfo();
}
}
system("pause");
system("cls");
}
int WorkerManager::isExist(int id)
{
int count = -1;
for (int i = 0; i < this->m_EmpNum; i++)
{
if (this->m_EmpArray[i]->m_Id == id)
{
count = i;
break;
}
}
return count;
}
void WorkerManager::del_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
}
else
{
int id = -1;
std::cout << "請輸入你要刪除的職工編號: ";
std::cin >> id;
int result = isExist(id);
if (result != -1)
{
for (int i = result; i < this->m_EmpNum - 1; i++)
{
this->m_EmpArray[i] = this->m_EmpArray[i + 1];
}
this->m_EmpNum--;
this->save();
std::cout << "刪除成功" << std::endl;
}
else
{
std::cout << "沒有找到職工編號為[" << result << "]的員工" << std::endl;
}
}
system("pause");
system("cls");
}
void WorkerManager::mod_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
}
else
{
int id = -1;
std::cout << "請輸入你要修改的職工編號: ";
std::cin >> id;
int result = isExist(id);
if (result != -1)
{
this->m_EmpArray[result]->showInfo();
int id;
std::string name;
int deptId;
std::cout << "請輸入修改的職工編號: ";
std::cin >> id;
std::cout << "請輸入修改的職工姓名: ";
std::cin >> name;
std::cout << "請選擇該職工的崗位" << std::endl;
std::cout << "1.普通員工" << std::endl;
std::cout << "2.經(jīng)理" << std::endl;
std::cout << "3.老板" << std::endl;
std::cin >> deptId;
Worker* modWorker = NULL;
switch (deptId)
{
case 1:
modWorker = new Employee(id, name, 1);
break;
case 2:
modWorker = new Manager(id, name, 2);
break;
case 3:
modWorker = new Boss(id, name, 3);
break;
default:
break;
}
this->m_EmpArray[result] = modWorker;
this->save();
std::cout << "修改成功,修改后的信息如下" << std::endl;
this->m_EmpArray[result]->showInfo();
}
else
{
std::cout << "沒有找到職工編號為[" << id << "]的員工" << std::endl;
}
}
system("pause");
system("cls");
}
void WorkerManager::find_Emp()
{
std::cout << "請輸入查找的方式:" << std::endl;
std::cout << "1.按員工編號查找" << std::endl;
std::cout << "2.按員工姓名查找" << std::endl;
int choise = 0;
std::cin >> choise;
if (choise == 1)
{
int id;
std::cout << "請輸入你要查找的員工編號: ";
std::cin >> id;
int result = isExist(id);
if (result != -1)
{
std::cout << "查找成功,員工信息如下:" << std::endl;
this->m_EmpArray[result]->showInfo();
}
else
{
std::cout << "沒有找到職工編號為[" << id << "]的員工" << std::endl;
}
}
else if (choise == 2)
{
std::string name;
std::cout << "請輸入你要查找的員工姓名: ";
std::cin >> name;
bool flag = false;
for (int i = 0; i < this->m_EmpNum; i++)
{
if (this->m_EmpArray[i]->m_Name == name)
{
std::cout << "查找成功,員工信息如下:" << std::endl;
this->m_EmpArray[i]->showInfo();
flag = true;
}
}
if (flag == false)
{
std::cout << "沒有找到職工姓名為[" << name << "]的員工" << std::endl;
}
}
else
{
std::cout << "輸入有誤,請重新輸入" << std::endl;
}
system("pause");
system("cls");
}
void WorkerManager::sort_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
system("pause");
system("cls");
}
else
{
std::cout << "請輸入排序的方式:" << std::endl;
std::cout << "1.按員工編號升序" << std::endl;
std::cout << "2.按員工編號降序" << std::endl;
int choise = 0;
std::cin >> choise;
//升序
for (int i = 0; i < this->m_EmpNum; i++)
{
int Min_Or_Max = i;
for (int j = i + 1; j < this->m_EmpNum; j++)
{
if (choise == 1)
{
//前一個大于后一個,就移動min指針
if (this->m_EmpArray[Min_Or_Max]->m_Id > this->m_EmpArray[j]->m_Id)
{
Min_Or_Max = j;
}
//前一個小于后一個,繼續(xù)往后比較
}
else if (choise == 2)
{
//前一個小于后一個,就移動max指針
if (this->m_EmpArray[Min_Or_Max]->m_Id < this->m_EmpArray[j]->m_Id)
{
Min_Or_Max = j;
}
//前一個大于后一個,繼續(xù)往后比較
}
}
//一輪比較后,如果標(biāo)記位置變了,交換位置
if (Min_Or_Max != i)
{
Worker* tempWorker = this->m_EmpArray[i];
this->m_EmpArray[i] = this->m_EmpArray[Min_Or_Max];
this->m_EmpArray[Min_Or_Max] = tempWorker;
}
}
this->save();
std::cout << "排序完成,排序后的結(jié)果如下:" << std::endl;
this->show_Emp();
}
}
void WorkerManager::clean_Emp()
{
if (this->m_FileIsEmpty)
{
std::cout << "文件不存在或記錄為空" << std::endl;
}
else
{
std::cout << "請確認是否需要清空?" << std::endl;
std::cout << "1.清空" << std::endl;
std::cout << "2.返回" << std::endl;
int choise = 0;
std::cin >> choise;
if (choise == 1)
{
std::ofstream ofs(FILENAME, std::ios::trunc);
ofs.close();
if (this->m_EmpArray != 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;
}
std::cout << "清空成功" << std::endl;
}
}
system("pause");
system("cls");
}
WorkerManager::~WorkerManager()
{
if (this->m_EmpArray != NULL)
{
for (int i = 0; i < this->m_EmpNum; i++)
{
delete this->m_EmpArray[i];
}
delete[] this->m_EmpArray;
this->m_EmpArray = NULL;
}
}
3. Main函數(shù)主體
負責(zé)調(diào)用我們寫好的函數(shù)文章來源:http://www.zghlxwxcb.cn/news/detail-623619.html
main.cpp
文章來源地址http://www.zghlxwxcb.cn/news/detail-623619.html
#include <iostream>
#include "workerManager.h"
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"
int main()
{
WorkerManager wm;
int choise = 0;
while (true)
{
wm.showMenu();
std::cout << "請輸入你的選擇: " << std::endl;
std::cin >> choise;
switch (choise)
{
case 0: //退出系統(tǒng)
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;
}
}
return 0;
}
到了這里,關(guān)于C++項目實戰(zhàn)之職工管理系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!