本案例为学习c++时跟着教程一起做的练习。
课程来源:黑马程序员
课程链接:
【黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难】https://www.bilibili.com/video/BV1et411b73Z?p=147&vd_source=142cd962633c250546e44894a32dfb0e
一、案例介绍
利用C++来实现一个基于多态的职工管理系统。公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职责。
管理系统中需要实现的功能如下:
-
退出管理程序:退出当前管理系统
-
增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为:职工编号、姓名、部门编号
-
显示职工信息:显示公司内部所有职工的信息
-
删除离职职工:删除指定的职工
-
修改职工信息:修改职工个人信息
-
查找职工信息:按照职工的编号或者职工的姓名进行查找相关的人员信息
-
按照编号排序:按照职工编号,进行排序,排序规则由用户指定
-
清空所有文档:清空文件中记录的所有职工信息 (清空前需要再次确认,防止误删)
⭐⭐在练习时,我对代码根据个人的编码习惯进行了一些修改,如封装了按照姓名或id进行查找的功能,在删除、修改、查找等功能中直接调用进行查找其数据索引等。
二、代码
1)头文件
worker基类:"worker.h"
#pragma once
#include <iostream>
#include <string>
using namespace std;
class worker {
public:
virtual void showInfo() = 0;//显示个人信息
virtual string GetJobTitle() = 0;//获取岗位名称
int worker_id;//职工编号
string name;//职工姓名
int DepartmentNumber;//职工所在部门编号
};
普通员工类:“OrdinaryEmployee.h”
#pragma once
#include<iostream>
#include"worker.h"
using namespace std;
class OrdinaryEmployee :public worker {
public:
OrdinaryEmployee(int id, string name, int DepNum);//构造函数
~OrdinaryEmployee();//析构函数
virtual void showInfo();//显示个人信息
virtual string GetJobTitle();//获取职工岗位名称
};
经理类:“CompanyManager.h”
#pragma once
#include<iostream>
#include"worker.h"
using namespace std;
class CompanyManager :public worker {
public:
CompanyManager(int id, string name, int DepNum);//构造函数
~CompanyManager();//析构函数
virtual void showInfo();//显示个人信息
virtual string GetJobTitle();//获取职工岗位名称
};
老板类:“Boss.h”
#pragma once
#include<iostream>
#include"worker.h"
using namespace std;
class Boss :public worker {
public:
Boss(int id, string name, int DepNum);//构造函数
~Boss();//析构函数
virtual void showInfo();//显示个人信息
virtual string GetJobTitle();//获取职工岗位名称
};
职工管理类:“Worker_Manager.h”
#pragma once
#include <iostream>
#include "worker.h"
#include "OrdinaryEmployee.h"
#include "CompanyManager.h"
#include "Boss.h"
#include <fstream>
#define FILENAME "WorkerFile.txt"
class Worker_Manager {
public:
Worker_Manager();//构造函数
~Worker_Manager();//析构函数
void show_Menu();//显示菜单
void exitSys();//退出系统
void add_emp();//添加职工
void save(); //保存到文件
bool FileIsEmpty;//判断文件是否为空
int getNumOfWorkerInTheFile();//获取文件中的人数
void init_EmployeeListData();//初始化员工数组
void show_WorkerList();//显示职工信息
int getIndexById(int id);//通过id获取员工信息在数组中的位置
int getIndexByName(string name);//通过名字获取员工信息在数组中的位置
int FindEmpIndex();//找到员工位置
void Del_Emp();//删除指定职工
void edit_Emp();//修改指定职工信息
void Find_Emp();//查找员工
void sort_Emp();//按职工号排序
void Clean_File();//清空文件
int workerNum;//当前员工数
worker** EmployeeArr;//员工数组指针
};
2)源文件
“职工管理系统.cpp”
/*
Author:Euan Cai
Creation time:2024-04-09
*/
#include <iostream>
#include "Worker_Manager.h"
using namespace std;
int main()
{
Worker_Manager manager;
int choice = 0;
while (true)
{
//展示菜单
manager.show_Menu();
cout << "请输入您的选择:" << endl;
cin >> choice;
switch (choice)
{
case 0: //退出系统
manager.exitSys();
break;
case 1: //添加职工
manager.add_emp();
break;
case 2: //显示职工
manager.show_WorkerList();
break;
case 3: //删除职工
manager.Del_Emp();
break;
case 4: //修改职工
manager.edit_Emp();
break;
case 5: //查找职工
manager.Find_Emp();
break;
case 6: //排序职工
manager.sort_Emp();
break;
case 7: //清空文件
manager.Clean_File();
break;
default:
system("cls");
break;
}
}
system("pause");
return 0;
}
“OrdinaryEmployee.cpp”
#include "OrdinaryEmployee.h"
OrdinaryEmployee::OrdinaryEmployee(int id, string name, int DepNum)
{
this->worker_id = id;
this->name = name;
this->DepartmentNumber = DepNum;
}
OrdinaryEmployee::~OrdinaryEmployee()
{
}
void OrdinaryEmployee::showInfo()
{
cout << "职工编号:" << this->worker_id
<< "\t职工名称:" << this->name
<< "\t岗位:" << this->GetJobTitle()
<< "\t岗位职责:完成经理交给的任务。" << endl;
}
string OrdinaryEmployee::GetJobTitle()
{
return string("普通员工");
}
“CompanyManager.cpp”
#include "CompanyManager.h"
CompanyManager::CompanyManager(int id, string name, int DepNum)
{
this->worker_id = id;
this->name = name;
this->DepartmentNumber = DepNum;
}
CompanyManager::~CompanyManager()
{
}
void CompanyManager::showInfo()
{
cout << "职工编号:" << this->worker_id
<< "\t职工名称:" << this->name
<< "\t岗位:" << this->GetJobTitle()
<< "\t岗位职责:完成老板交给的任务,并下发任务给员工。" << endl;
}
string CompanyManager::GetJobTitle()
{
return string("经理");
}
“Boss.cpp”
#include "Boss.h"
Boss::Boss(int id, string name, int DepNum)
{
this->worker_id = id;
this->name = name;
this->DepartmentNumber = DepNum;
}
Boss::~Boss()
{
}
void Boss::showInfo()
{
cout << "职工编号:" << this->worker_id
<< "\t职工名称:" << this->name
<< "\t岗位:" << this->GetJobTitle()
<< "\t岗位职责:管理公司所有事物。" << endl;
}
string Boss::GetJobTitle()
{
return string("老板");
}
“Worker_Manager.cpp”
/*
管理类负责的内容:
* 与用户的沟通菜单界面
* 对职工增删改查的操作
* 与文件的读写交互
*/
#include "Worker_Manager.h"
Worker_Manager::Worker_Manager()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
if (!ifs.is_open()) {
cout << "====当前系统中职工名单文件不存在!!====" << endl;
this->workerNum = 0;
this->EmployeeArr = NULL;
this->FileIsEmpty = true;
ifs.close();
return;
}
char ch;
ifs >> ch;
if (ifs.eof()) {
cout << "====当前系统中职工名单文件存在但内容为空!!====" << endl;
this->workerNum = 0;
this->EmployeeArr = NULL;
this->FileIsEmpty = true;
ifs.close();
return;
}
int num = this->getNumOfWorkerInTheFile();
cout << "====当前系统中依据职工名单文件共识别到" << num << "个职工数据!!====" << endl;
this->workerNum = num;
this->FileIsEmpty = false;
this->EmployeeArr = new worker * [this->workerNum];
this->init_EmployeeListData();
}
Worker_Manager::~Worker_Manager()
{
//释放堆区数据
if (this->EmployeeArr != NULL) {
delete[] this->EmployeeArr;
}
}
void Worker_Manager::show_Menu()
{
std::cout << "********************************************" << std::endl;
std::cout << "********* 欢迎使用职工管理系统! **********" << 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 Worker_Manager::exitSys()
{
std::cout << "欢迎下次使用!!" << std::endl;
system("pause");
exit(0);//关闭所有文件,终止正在执行的进程。stdlib.h: void exit(int status); 参数:status表示程序退出的返回值.
}
void Worker_Manager::add_emp()
{
std::cout << "请输入要添加的职工数量:" << std::endl;
int addNum = 0;
cin >> addNum;
if (addNum > 0) {
int newSize = this->workerNum + addNum;
worker** newSpace = new worker * [newSize];
if (this->EmployeeArr != NULL) {
for (int i = 0; i < this->workerNum; i++) {
newSpace[i] = this->EmployeeArr[i];
}
}
for (int i = 0; i < addNum; i++) {
int id;
string name;
int type;
std::cout << "请输入第" << i + 1 << "个新员工的编号:" << endl;
cin >> id;
std::cout << "请输入第" << i + 1 << "个新员工的姓名:" << endl;
cin >> name;
cout << "请选择该职工的岗位:" << endl;
cout << "1、普通职工" << endl;
cout << "2、经理" << endl;
cout << "3、老板" << endl;
cin >> type;
worker* worker = NULL;
switch (type)
{
case 1:
worker = new OrdinaryEmployee(id, name, type);
break;
case 2:
worker = new CompanyManager(id, name, type);
break;
case 3:
worker = new Boss(id, name, type);
break;
default:
break;
}
newSpace[this->workerNum + i] = worker;
}
delete[] this->EmployeeArr;
this->EmployeeArr = newSpace;
this->workerNum = newSize;
this->save();
this->FileIsEmpty = false;
cout << "成功增加" << addNum << "个新员工!!" << endl;
}
else {
cout << "输入有误!!" << endl;
}
system("pause");
system("cls");
}
void Worker_Manager::save()
{
ofstream ofs;
ofs.open(FILENAME, ios::out);
for (int i = 0; i < this->workerNum; i++) {
ofs << this->EmployeeArr[i]->worker_id << " "
<< this->EmployeeArr[i]->name << " "
<< this->EmployeeArr[i]->DepartmentNumber << endl;
}
ofs.close();
}
int Worker_Manager::getNumOfWorkerInTheFile()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int id;
string name;
int Did;
int worker_Num = 0;
while (ifs >> id && ifs >> name && ifs >> Did) //在C++中,ifstream的>>--提取符直接就是以空格为分隔符读取文件内容。
{
worker_Num++;
}
ifs.close();
return worker_Num;
}
void Worker_Manager::init_EmployeeListData()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int id;
string name;
int deId;
int index = 0;
while (ifs >> id && ifs >> name && ifs >> deId) {
worker* worker = NULL;
if (deId == 1) {
worker = new OrdinaryEmployee(id, name, deId);
}
else if (deId == 2) {
worker = new CompanyManager(id, name, deId);
}
else {
worker = new Boss(id, name, deId);
}
this->EmployeeArr[index++] = worker;
}
ifs.close();
cout << "成功由文件导入" << index << "个职工信息!!" << endl;
cout << "系统初始化成功!!" << endl;
}
void Worker_Manager::show_WorkerList()
{
if (this->FileIsEmpty) {
cout << "文件不存在或文件为空,系统中找不到职工信息。" << endl;
}
else {
for (int i = 0; i < workerNum; i++) {
this->EmployeeArr[i]->showInfo();
}
}
system("pause");
system("cls");
}
//根据id查找,若查找成功,返回该数据的索引,若查找失败,返回-1.
int Worker_Manager::getIndexById(int id)
{
int index = -1;
for (int i = 0; i < this->workerNum; i++) {
if (this->EmployeeArr[i]->worker_id == id) {
index = i;
break;
}
}
return index;
}
//根据姓名查找,若查找成功,返回该数据的索引,若查找失败,返回-1.
int Worker_Manager::getIndexByName(string name)
{
int index = -1;
for (int i = 0; i < this->workerNum; i++) {
if (this->EmployeeArr[i]->name == name) {
index = i;
break;
}
}
return index;
}
int Worker_Manager::FindEmpIndex()
{
FIND:
cout << "请输入对于该员工的查找方式:" << endl;
cout << "1、通过id查找。" << endl;
cout << "2、通过姓名查找。" << endl;
int choice = 0;
int index = -1;
cin >> choice;
if (choice == 1) {
cout << "请输入要查找的员工编号:" << endl;
int del_id = 0;
cin >> del_id;
index = this->getIndexById(del_id);
}
else if (choice == 2) {
cout << "请输入要查找的员工姓名:" << endl;
string del_name = "";
cin >> del_name;
index = this->getIndexByName(del_name);
}
else {
cout << "无法识别您选择的方式,请重试。" << endl;
goto FIND;
}
return index;
}
void Worker_Manager::Del_Emp()
{
cout << "======删除指定职工信息======" << endl;
if (this->FileIsEmpty) {
cout << "文件不存在或为空,系统中暂不存在任何职工数据!!" << endl;
}
else {
cout << "请指定要删除的职工id或姓名:" << endl;
int index = FindEmpIndex();
if (index != -1) {
for (int i = index; i < this->workerNum - 1; i++) {
this->EmployeeArr[i] = this->EmployeeArr[i + 1];
}
this->workerNum--;
this->save();
cout << "删除成功。" << endl;
}
else {
cout << "未找到该职工,删除失败。" << endl;
}
}
system("pause");
system("cls");
}
void Worker_Manager::edit_Emp()
{
cout << "======修改指定职工信息======" << endl;
if (this->FileIsEmpty) {
cout << "文件不存在或为空,系统中暂不存在任何职工数据!!" << endl;
}
else {
cout << "请指定要修改的职工id或姓名:" << endl;
int index = FindEmpIndex();
if (index != -1) {
cout << "查找到该员工,其修改前的信息为:" << endl;
this->EmployeeArr[index]->showInfo();
int newId = 0;
string newName = "";
int newDeNum = 0;
cout << "请输入新的ID:" << endl;
cin >> newId;
cout << "请输入新的姓名:" << endl;
cin >> newName;
cout << "该员工修改前的职务为:" << this->EmployeeArr[index]->GetJobTitle() << ",请问要修改为:" << endl;
cout << "1、普通职工" << endl;
cout << "2、经理" << endl;
cout << "3、老板" << endl;
cin >> newDeNum;
worker* worker = NULL;
switch (newDeNum)
{
case 1:
worker = new OrdinaryEmployee(newId, newName, newDeNum);
break;
case 2:
worker = new CompanyManager(newId, newName, newDeNum);
break;
case 3:
worker = new Boss(newId, newName, newDeNum);
break;
default:
cout << "职位选项输入有误!" << endl;
break;
}
this->EmployeeArr[index] = worker;
this->save();
cout << "修改成功。" << endl;
cout << "修改后的信息为:" << endl;
this->EmployeeArr[index]->showInfo();
}
else {
cout << "未找到该职工,修改失败。" << endl;
}
}
system("pause");
system("cls");
}
void Worker_Manager::Find_Emp()
{
cout << "======查找职工信息======" << endl;
if (this->FileIsEmpty) {
cout << "文件不存在或为空,系统中暂不存在任何职工数据!!" << endl;
}
else {
cout << "请指定要查找的职工id或姓名:" << endl;
int index = FindEmpIndex();
if (index != -1) {
cout << "查找成功,该职工的信息如下:" << endl;
this->EmployeeArr[index]->showInfo();
}
else {
cout << "未找到该职工。" << endl;
}
}
system("pause");
system("cls");
}
void Worker_Manager::sort_Emp()
{
if (this->FileIsEmpty)
{
cout << "文件不存在或记录为空!" << endl;
system("pause");
system("cls");
}
else {
cout << "请选择排序方式: " << endl;
cout << "1、按职工号进行升序" << endl;
cout << "2、按职工号进行降序" << endl;
int choice = 0;
cin >> choice;
if (choice != 1 && choice != 2) {
cout << "输入有误,请确认后再试。" << endl;
return;
}
for (int i = 0; i < this->workerNum; i++) {
int flag = i;
for (int j = i + 1; j < this->workerNum; j++) {
if (choice == 1) {
if (this->EmployeeArr[i]->worker_id > this->EmployeeArr[j]->worker_id) {
flag = j;
}
}
else {
if (this->EmployeeArr[i]->worker_id < this->EmployeeArr[j]->worker_id) {
flag = j;
}
}
}
if (i != flag) {
worker* temp = this->EmployeeArr[i];
this->EmployeeArr[i] = this->EmployeeArr[flag];
this->EmployeeArr[flag] = temp;
}
}
this->save();
cout << "排序成功,排序后结果为:" << endl;
this->show_WorkerList();
}
}
void Worker_Manager::Clean_File()
{
cout << "确认清空吗?" << endl;
cout << "1、确认" << endl;
cout << "2、返回" << endl;
int select = 0;
cin >> select;
if (select == 1)
{
ofstream ofs(FILENAME, ios::trunc);//打开模式 ios::trunc 表示如果存在删除文件并重新创建
ofs.close();
if (this->EmployeeArr != NULL) {
for (int i = 0; i < this->workerNum; i++) {
if (this->EmployeeArr[i] != NULL) {
delete this->EmployeeArr[i];
this->EmployeeArr[i] = NULL;
}
}
this->workerNum = 0;
delete[]this->EmployeeArr;
this->EmployeeArr = NULL;
this->FileIsEmpty = true;
}
cout << "清空成功!!" << endl;
}
system("pause");
system("cls");
}