蘋果:應用側載法案將使得惡意軟體、詐騙和資料剝削氾濫
- 職工管理系統
職工管理系統
一、 需求
職工管理系統可以用來管理公司所有員工的資訊
本次利用C++來實現一個基於多型的職工管理系統
公司中職工分為三類:普通職工、經理、老闆。顯示資訊時,需要顯示職工編號、職工姓名、職工崗位以及職責
普通員工職責:完成經理佈置的任務
經理職責:完成老闆佈置的任務,並下發給員工
老闆職責:管理公司所有事務
管理功能中需要實現的功能
- 退出管理程式:退出當前管理系統
- 增加職工資訊:實現批量新增職工資訊,將資訊錄入到檔案中,職工資訊為:職工編號、姓名、部門編號
- 顯示職工資訊:顯示公司內部所有職工的資訊
- 刪除離職職工:按照編號刪除指定的職工
- 修改職工資訊:按照編號修改職工個人資訊
- 查詢職工資訊:按照職工的編號或者姓名進行查詢相關的人員資訊
- 按照編號排序:按照職工編號,進行排序,排序規則由使用者指定
- 清空所有文件:清空檔案中記錄的所有職工資訊(清空前需要再次確認,防止誤觸)
二、 建立管理類
管理類賦值的內容如下
- 與使用者的溝通選單介面
- 對職工增刪改查的操作
- 與檔案的讀寫互動
1、建立檔案
在標頭檔案和原始檔的資料夾下面分別建立 workerManger.h 和 workerManger.cpp 檔案
2、 標頭檔案實現
在 workerManager.h 中設計管理類
#pragma once // 防止標頭檔案重複包含
#include <iostream> // 包含輸入輸出流標頭檔案
using namespace std; // 使用標準名稱空間
class WorkerManager
{
public:
// 建構函式
WorkerManager();
// 解構函式
~WorkerManager();
};
3、 原始檔實現
在 workerManager.cpp 中將建構函式和解構函式空實現補全
#include "workerManager.h"
WorkerManager::WorkerManager() {}
WorkerManager::~WorkerManager() {}
三、 選單功能
功能描述:與使用者的溝通介面
1、 新增成員函式
在管理類 workerManager.h 中新增成員函式 void Show_Menu();
class WorkerManager
{
public:
// 建構函式
WorkerManager();
// 展示選單
void Show_Menu();
// 解構函式
~WorkerManager();
};
2、 功能實現
在管理類 workerManager.cpp 中實現 Show_Menu() 函式
void WorkerManager::Show_Menu()
{
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;
}
3、 測試選單功能
在 職工管理系統.cpp 中測試選單功能
#include <iostream>
using namespace std;
#include "workerManager.h"
int main()
{
// 例項化管理物件
WorkerManager wm;
// 呼叫成員函式
wm.Show_Menu();
system("pause");
return 0;
}
四、 退出功能
1、 提供功能介面
在 main() 函式中提供分支選擇,提供每個功能介面
int main()
{
WorkerManager wm;
int choice;
while (true)
{
// 展示選單
wm.Show_Menu();
cout << "請輸入您的選擇:" << endl;
cin >> choice;
switch (choice)
{
case 0: // 退出系統
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;
}
}
system("pause");
return 0;
}
2、 實現退出功能
在 workerManager.h 中提供退出系統的成員函式 void exitSystem();
在 workerManager.cpp 中提供具體的功能實現
void WorkerManager::exitSystem()
{
cout << "歡迎下次使用" << endl;
system("pause");
exit(0); // 退出程式
}
五、 建立職工類
1、 建立職工抽象類
職工分為:普通員工、經理、老闆
將三種職工抽象到一個類(worker)中,利用多型管理不同職工種類
職工屬性分為:職工編號、職工姓名、職工所在部門
職工的行為:崗位職責資訊描述、獲取崗位名稱
在標頭檔案下,建立檔案 worker.h 檔案並且新增程式碼
#pragma once
#include <iostream>
using namespace std;
// 員工抽象類
class Worker
{
public:
virtual void showInfo() = 0; // 顯示職工資訊
virtual string getDeptName() = 0; // 返回崗位名稱
int m_Id; // 職工編號
string m_Name; // 職工姓名
int m_DeptId; // 部門編號
};
2、 建立普通員工類
在標頭檔案下,建立 employee.h 標頭檔案,並且新增程式碼
#pragma once
#include "worker.h"
#include <iostream>
using namespace std;
class Employee : public Worker
{
public:
Employee(int id, string name, int did);
virtual void showInfo(); // 顯示職工資訊
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 << "職工編號:" << this->m_Id
<< "\t職工姓名:" << this->m_Name
<< "\t職工崗位:" << this->getDeptName()
<< "\t崗位職責:完成經理佈置的任務" << endl;
}
string Employee::getDeptName() // 返回崗位名稱
{
return string("員工");
}
簡單測試
在 職工管理系統.cpp 中新增測試程式碼
Worker* worker = new Employee(1, "張三", 1);
worker->showInfo();
3、 建立經理類
經理類繼承職工抽象類,並重寫父類中純虛擬函式和普通員工類類似
在標頭檔案和原始檔的資料夾下分別建立 manager.h 和 manager.cpp 檔案
manager.h 中程式碼如下
#pragma once
#include <iostream>
using namespace std;
#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 << "職工編號:" << this->m_Id
<< "\t職工姓名:" << this->m_Name
<< "\t職工崗位:" << this->getDeptName()
<< "\t崗位職責:完成老闆佈置的任務,並下發給員工" << endl;
}
string Manager::getDeptName()
{
return string("經理");
}
4、 建立老闆類
老闆類繼承職工抽象類,並重寫父類中純虛擬函式和普通員工類類似
在標頭檔案和原始檔的資料夾下分別建立 boss.h 和 boss.cpp 檔案
在 boss.h 中新增程式碼
#pragma once
#include <iostream>
using namespace std;
#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 << "職工編號:" << this->m_Id
<< "\t職工姓名:" << this->m_Name
<< "\t職工崗位:" << this->getDeptName()
<< "\t崗位職責:管理公司所有事務" << endl;
}
string Boss::getDeptName()
{
return string("老闆");
}
5、 程式碼測試
#include <iostream>
using namespace std;
#include "workerManager.h"
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"
int main()
{
Worker* worker = NULL;
worker = new Employee(1, "張三", 1);
worker->showInfo();
delete worker;
worker = new Manager(2, "李四", 2);
worker->showInfo();
delete worker;
worker = new Boss(3, "Ja", 3);
worker->showInfo();
delete worker;
system("pause");
return 0;
}
六、 新增職工類
功能描述:批量新增職工,並且儲存到檔案中
1、 功能分析
使用者在批量新增時,可能會建立不同種類的員工
如果想將所有不同種類的員工放入到一個數組中,可以將所有員工的指標維護到一個數組裡面
如果想在程式中維護這個不定長的陣列,可以將陣列建立到堆區,並利用 Worker** 的指標維護
2、 功能實現
在 WorkerManager.h 標頭檔案中新增成員屬性和成員函式
// 記錄檔案中的人數
int m_EmpNum;
// 員工陣列的指標
Worker** m_EmpArr = NULL;
// 注意要匯入 worker 標頭檔案
// 新增職工
void Add_Emp();
workerManager.cpp 實現該函式
#include "employee.h"
#include "manager.h"
#include "boss.h"
// 初始化成員屬性
WorkerManager::WorkerManager(){
// 初始化屬性
this->m_EmpNum = 0;
this->m_EmpArr = NULL;
}
void WorkerManager::Add_Emp()
{
int num; // 儲存使用者輸入數量
cout << "請輸入新增職工的人數:" << endl;
cin >> num;
if (num > 0)
{
// 新增人數
// 計算新增空間大小
int newSize = this->m_EmpNum + num; // 新空間大小 = 原來的人數 + 新增人數
// 開闢空間
Worker** newSpace = new Worker* [newSize];
// 將原來空間下資料,拷貝到新空間下
if (this->m_EmpArr)
{
for (int i = 0; i < this->m_EmpNum; i++)
{
newSpace[i] = this->m_EmpArr[i];
}
}
// 新增資料
for (int i = 0; i < num; i++)
{
int id;
string name;
int dSelect; // 部門選擇
cout << "請輸入第" << i + 1 << "個新員工的編號" << endl;
cin >> id;
cout << "請輸入該新員工的姓名" << endl;
cin >> name;
cout << "請選擇該新員工的部門" << endl;
cout << "1、普通員工" << endl;
cout << "2、經理" << endl;
cout << "3、老闆" << endl;
cin >> dSelect;
Worker* worker = NULL;
switch (dSelect)
{
case 1:
worker = new Employee(id, name, dSelect);
break;
case 2:
worker = new Manager(id, name, dSelect);
break;
case 3:
worker = new Boss(id, name, dSelect);
break;
default:
cout << "請按照要求輸入!" << endl;
break;
}
// 將建立的職工指標儲存到職工陣列中
newSpace[this->m_EmpNum + i] = worker;
}
// 釋放原有的空間
delete[] this->m_EmpArr;
// 更改新空間的指向
this->m_EmpArr = newSpace;
// 更新職工人數
this->m_EmpNum = newSize;
this->save();
cout << "成功新增" << num << "名職工" << endl;
}
else
{
// 返回
cout << "輸入錯誤!" << endl;
}
}
delete[] array; 釋放陣列空間
七、 檔案互動
1、 寫檔案
功能描述:對檔案進行寫入
在上一個新增功能中,我們只是將所有的資料新增到了記憶體中,一旦程式結束就無法儲存了。因此,檔案管理類中需要一個與檔案進行互動的功能,對於檔案進行讀寫操作
1.1 設定檔案路徑
首先,我們將檔案路徑,在 workerManager.h 中新增巨集常量,並且包含 <fstream> 檔案
#include <fstream>
#define FILENAME "empFile.txt"
1.2 成員函式宣告
在 workerManager.h 裡新增成員函式
// 儲存
void save();
1.3 儲存功能實現
void WorkerManager::save()
{
ofstream ofs(FILENAME, ios::out);
// 將每個資料寫入到檔案中
for (int i = 0; i < this->m_EmpNum; i++)
{
ofs << this->m_EmpArr[i]->m_Id << " "
<< this->m_EmpArr[i]->m_Name << " "
<< this->m_EmpArr[i]->m_DeptId << endl;
}
ofs.close();
}
2、 讀檔案
功能描述:將檔案中的內容讀取到程式中
雖然我們實現了新增職工後儲存檔案的操作,但是每次開始執行程式,並沒有將檔案中資料讀取到程式中
而我們的程式功能中海油清空檔案的需求
因此,建構函式初始化資料的情況分為三種
- 第一次使用,檔案未建立
- 檔案存在,但是資料被使用者清空
- 檔案存在,並且儲存職工所有資料
2.1 檔案未建立
在 workerManager.h 中新增新的成員屬性 m_FilesEmpty 標誌檔案是否為空
// 判斷檔案是否為空
bool m_FilesEmpty;
修改 workerManager.cpp 中建構函式程式碼
WorkerManager::WorkerManager(){
// 初始化屬性
// 如果檔案不存在
ifstream ifs(FILENAME, ios::in); // 讀檔案
if (!ifs.is_open())
{
this->m_EmpNum = 0;
this->m_EmpArr = NULL;
this->m_FilesEmpty = true;
ifs.close();
return;
}
}
2.2 檔案存在
2.2.1 檔案資料為空
在 workerManager.cpp 中的建構函式追加程式碼
// 檔案存在資料為空
char ch;
ifs >> ch;
if (ifs.eof())
{
this->m_EmpNum = 0;
this->m_EmpArr = NULL;
this->m_FilesEmpty = true;
ifs.close();
return;
}
ifstream ifs(FILENAME, ios::in); // 讀檔案 char ch; ifs >> ch; isEmpty = ifs.eof(); // 判斷檔案是否為空的方法
2.2.2 檔案資料存在
2.2.2.1 獲取記錄的職工人數
在 workerManager.h 中新增成員函式 int get_EmpNum();
// 統計員工人數
int get_EmpNum();
在 workerManager.cpp 實現
int WorkerManager::get_EmpNum()
{
ifstream ifs(FILENAME, ios::in);
int id;
string name;
int did;
int num = 0;
while (ifs >> id && ifs >> name && ifs >> did)
{
// 統計人數
num++;
}
return num;
}
2.2.2.2 初始化員工
在 workerManager.h 中新增成員函式void init_Emp();
// 初始化員工
void init_Emp();
在 workerManager.cpp 中實現
void WorkerManager::init_Emp()
{
// 初始化員工
ifstream ifs(FILENAME, ios::in);
int index = 0;
int id;
string name;
int did;
while (ifs >> id && ifs >> name && ifs >> 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;
}
this->m_EmpArr[index] = worker;
index++;
}
ifs.close(); // 關閉檔案
}
在建構函式追加
// 檔案存在且有資料
this->m_EmpNum = this->get_EmpNum();
// 開闢空間
this->m_EmpArr = new Worker * [this->m_EmpNum];
// 將檔案中的資料,存到陣列中
this->init_Emp();
八、 顯示員工
功能描述:顯示當前所有員工資訊
在 workerManager.h 中新增成員函式void Show_Emp();
// 顯示職工資訊
void Show_Emp();
在 workerManager.cpp 中實現成員函式
void WorkerManager::Show_Emp()
{
// 顯示職工
// 判斷檔案是否為空
if (this->m_FilesEmpty)
{
cout << "檔案不存在或資料為空" << endl;
}
else
{
for (int i = 0; i < m_EmpNum; i++)
{
// 利用多型呼叫程式介面
this->m_EmpArr[i]->showInfo();
}
}
// 按任意鍵清屏
system("pause");
system("cls");
}
九、 刪除職工
功能描述:按照職工的編號進行刪除職工操作
1、 刪除職工函式宣告
在 workerManager.h 中新增成員函式void Del_Emp();
// 刪除職工函式
void Del_Emp();
2、 職工是否存在函式宣告
很多功能都需要用到根據職工是否存在來進行操作,如:刪除職工、修改職工、查詢職工
因此,新增該函式,以便後續使用
在 workerManager.h 中新增成員函式int IsExist(int id);
// 判斷職工是否存在,存在返回索引,不存在返回 -1
int IsExist(int id); // id查詢
int IsExist(string name); // name查詢
3、 職工是否存在函式實現
在 workerManager.h 中新增函式
int WorkerManager::IsExist(int id)
{
// 判斷職工是否存在,存在返回索引,不存在返回 -1
for (int i = 0; i < this->m_EmpNum; i++)
{
if (this->m_EmpArr[i]->m_Id == id)
{
return i;
}
}
return -1; // 沒找到返回-1
}
int WorkerManager::IsExist(string name)
{
for (int i = 0; i < this->m_EmpNum; i++)
{
if (this->m_EmpArr[i]->m_Name == name)
{
return i;
}
}
return -1;
}
4、 刪除職工函式實現
在 workerManager.cpp 中新增函式
void WorkerManager::Del_Emp()
{
// 刪除職工函式
if (this->m_FilesEmpty)
{
cout << "檔案不存在或資料為空" << endl;
return;
}
else
{
// 按照職工編號刪除職工
int id;
cout << "請輸入要刪除的職工編號:" << endl;
cin >> id;
int num = this->IsExist(id);
if (num == -1) // 說明職工不存在
{
cout << "該職工不存在!";
return;
}
else
{
for (int i = num; i < m_EmpNum - 1 - num; i++)
{
this->m_EmpArr[i] = this->m_EmpArr[i + 1];
}
this->m_EmpNum--; // 更新人員個數
this->save();
cout << "刪除成功" << endl;
system("pause");
system("cls");
}
}
}
十、 修改職工
功能描述:能夠按照職工的編號對職工資訊進行修改並儲存
1、 函式宣告
在 workerManager.h 中新增成員函式void Mod_Emp();
// 修改職工
void Mod_Emp();
2、 函式實現
在 workerManager.cpp 中實現成員函式
void WorkerManager::Mod_Emp()
{
if (this->m_FilesEmpty)
{
cout << "檔案不存在或資料清空" << endl;
}
else
{
int id;
cout << "請輸入修改職工的編號:" << endl;
cin >> id;
int index = this->IsExist(id);
if (index == -1)
{
cout << "該職工不存在" << endl;
}
else
{
// 職工存在
delete this->m_EmpArr[index];
int newId;
string newName;
int dSelect;
cout << "請輸入修改內容:" << endl;
cout << "請輸入員工的編號" << endl;
cin >> newId;
cout << "請輸入該員工的姓名" << endl;
cin >> newName;
cout << "請選擇該員工的部門" << endl;
cout << "1、普通員工" << endl;
cout << "2、經理" << endl;
cout << "3、老闆" << endl;
cin >> dSelect;
Worker* worker = NULL;
switch (dSelect)
{
case 1:
worker = new Employee(newId, newName, dSelect);
break;
case 2:
worker = new Manager(newId, newName, dSelect);
break;
case 3:
worker = new Boss(newId, newName, dSelect);
break;
default:
cout << "請按照要求輸入!" << endl;
break;
}
this->m_EmpArr[index] = worker; // 重新儲存
cout << "修改成功" << endl;
this->save();
}
}
system("pause");
system("cls");
}
十一、 查詢職工
功能描述:提供兩種查詢職工的方式,一種按照職工編號,一種按照職工姓名
1、 查詢職工函式宣告
在 workerManager.h 中新增成員函式宣告void Find_Emp();
// 查詢職工
void Find_Emp();
2、 查詢職工函式實現
void WorkerManager::Find_Emp()
{
if (this->m_FilesEmpty)
{
cout << "檔案為空或不存在" << endl;
}
else
{
cout << "請輸入查詢方式:" << endl
<< "1、 按照職工編號查詢" << "\n"
<< "2、 按照職工姓名查詢" << endl;
int choice;
cin >> choice;
switch (choice)
{
case 1:
{
int id;
cout << "請輸入職工編號:" << endl;
cin >> id;
int index = this->IsExist(id);
if (index == -1)
{
cout << "該職工不存在" << endl;
}
else
{
m_EmpArr[index]->showInfo();
}
}
break;
case 2:
{
cout << "請輸入職工姓名:" << endl;
string name;
cin >> name;
int index = this->IsExist(name);
if (index == -1)
{
cout << "該職工不存在" << endl;
}
else
{
m_EmpArr[index]->showInfo();
}
}
break;
default:
cout << "請按照要求輸入" << endl;
break;
}
}
system("pause");
system("cls");
}
十二、 排序
功能描述:按照職工編號進行排序,排序的順序由使用者指定
1、 函式宣告
在 workerManager.h 中新增成員函式void Sort_Emp();
// 排序
void Sort_Emp();
2、 函式實現
在 workerManager.cpp 中新增函式
void WorkerManager::Sort_Emp()
{
if (this->m_FilesEmpty)
{
cout << "檔案不存在或檔案為空" << endl;
system("pause");
system("cls");
return;
}
else
{
cout << "請輸入排序方式:" << endl
<< "1、 升序排序" << endl
<< "2、 降序排序" << endl;
int choice;
cin >> choice;
for (int i = 0; i < this->m_EmpNum; i++)
{
int minOrmax = i;
for (int j = i + 1; j < this->m_EmpNum; j++)
{
if (choice == 1) // 升序
{
if (this->m_EmpArr[minOrmax]->m_Id > this->m_EmpArr[j]->m_Id)
{
minOrmax = j;
}
}
else
{
if (this->m_EmpArr[minOrmax]->m_Id < this->m_EmpArr[j]->m_Id)
{
minOrmax = j;
}
}
}
Worker* temp = m_EmpArr[minOrmax];
m_EmpArr[minOrmax] = m_EmpArr[i];
m_EmpArr[i] = temp;
}
cout << "排序成功" << endl;
this->Show_Emp(); // 展示資訊
}
}
選擇排序
for (int i = 0; i < this->m_EmpNum; i++) { int minOrmax = i; for (int j = i + 1; j < this->m_EmpNum; j++) { if (choice == 1) // 升序 { if (this->m_EmpArr[minOrmax]->m_Id > this->m_EmpArr[j]->m_Id) { minOrmax = j; } } else { if (this->m_EmpArr[minOrmax]->m_Id < this->m_EmpArr[j]->m_Id) { minOrmax = j; } } } Worker* temp = m_EmpArr[minOrmax]; m_EmpArr[minOrmax] = m_EmpArr[i]; m_EmpArr[i] = temp; }
十三、 清空檔案
功能描述:將檔案中記錄資料清空
1、 清空函式宣告
在 workerManager.h 中新增成員函式void Clean_File();
// 清空檔案
void Clean_File();
2、 函式實現
在 workerManager.cpp 中實現函式
void WorkerManager::Clean_File()
{
cout << "確認清空嗎?" << endl
<< "1、 確認" << endl
<< "2、 取消" << endl;
int choice;
cin >> choice;
switch (choice)
{
case 1:
{
cout << "清除成功" << endl;
// 開啟模式:ios::trunc,如果存在刪除檔案並重新建立
ofstream ofs(FILENAME, ios::trunc);
ofs.close();
if (this->m_EmpArr) // 刪除堆區資料
{
for (int i = 0; i < m_EmpNum; i++)
{
if (this->m_EmpArr[i])
{
delete this->m_EmpArr[i];
}
}
// 刪除指標
this->m_EmpNum = 0;
delete[] this->m_EmpArr;
this->m_EmpArr = NULL;
this->m_FilesEmpty = true;
}
break;
}
case 2:
cout << "正在取消" << endl;
break;
default:
cout << "請按要求輸入" << endl;
break;
}
system("pause");
system("cls");
}
本文來自部落格園,作者:A-L-Kun,轉載請註明原文連結:https://www.cnblogs.com/liuzhongkun/p/15894024.html