C++——基于多态的职工管理系统
一个基于多态的C++项目,断断续续写了两三天。获得一些收获和大家分享。欢迎指正交流。
一、包含功能
********* 欢迎使用职工管理系统 *********
************ 0.退出管理系统 ************
************ 1.增加职工信息 ************
************ 2.显示职工信息 ************
************ 3.删除离职职工 ************
************ 4.修改职工信息 ************
************ 5.查找职工信息 ************
************ 6.按照编号排序 ************
************ 7.清空所有文档 ************
******************************************
二、主要实现技术总结
(一)多态
职工类为接口,派生出老板类、经理类、员工类,分别实现不同的岗位名称和岗位职责的输出。
(二)对象
C++有一种万物皆可为对象的概念,整个程序就可以视作一个管理程序的对象,创建WorkerManager类,逐一实现:菜单展示、增加职工、显示职工、删除职工、修改职工、查找职工以及排序、清空等多种功能。
(三)循环
程序的交互过程均需要用到循环,在循环过程中处理交互的各种情况。例如:
1、用户的主菜单选择以及返回主菜单。
2、用户的输入不合法时,重新输入。
3、用户完成工作后,返回上级或者返回主菜单。
(四)文件读写
通过文件读写实现数据的操作,写文件时先将职工数量写入第一行,方便后续操作
三、作业总结
根据程序的不同需求设置清晰的架构脉络,主线程序代码要足够健壮(没有bug),再逐一实现其他功能函数。将程序分割为多个模块再组合起来实现复杂的需求,是一个项目成功的必备条件,这也是C++的封装特性的体现。
四、上代码
main.cpp
#include<iostream>
using namespace std;
#include"workerManager.h"
#include"Worker.h"int main(int argc, char const *argv[]) {//创建职工管理类对象workerManager WM;//定义用户选项int choice = -1;while (true) {WM.Show_Menu();cout << "请输入您的选择" << endl;cin >> choice;switch (choice) {case 0: //退出系统WM.Exit_System();break;case 1: //增加职工WM.Add_Worker();break;case 2: //显示职工WM.Show_Worker();break;case 3: //删除职工WM.Del_Worker();break;case 4: //修改职工WM.Mod_Worker();break;case 5: //查找职工WM.Search_Worker();break;case 6: //编号排序WM.Sort_ID();break;case 7: //清空文档WM.Clear_Worker();break;}system("pause");system("cls");}return 0;
}
Worker.h——职工类
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<iomanip> //c++标准库,主要功能设置输出格式
enum Post
{BOSS,MANAGER,EMPLOYEE,POSTCOUNT
};
//职工类
class Worker
{
public:int m_id; //职工编号string m_name; //职工姓名int m_post; //岗位编号//显示职工信息virtual void show_Info() = 0;//获得职工岗位virtual string get_Postname() = 0;
};
//老板类
class Boss :public Worker {
public:Boss(int id, string name, int post);void show_Info();string get_Postname();
};
//经理类
class Manager :public Worker {
public:Manager(int id, string name, int post);void show_Info();string get_Postname();
};
//普通员工类
class Employee :public Worker {
public:Employee(int id, string name, int post);void show_Info();string get_Postname();
};
Worker.cpp——职工类成员函数实现
#include "Worker.h"Boss::Boss(int id, string name, int post)
{m_id = id;m_name = name;m_post = post;
}
void Boss::show_Info()
{//设置输出编号占两个字符宽度,空位用'0'填充,通过setiosflag(ios::left/right)可以调整靠左或者靠右cout << "序号:" << setw(2) << setfill('0') << m_id<< "\t姓名:" << m_name<< "\t岗位:" << get_Postname()<< "\t岗位职责:负责公司全面工作,安排经理的工作" << endl;
}
string Boss::get_Postname()
{return string("老板");
}Manager::Manager(int id, string name, int post)
{m_id = id;m_name = name;m_post = post;
}
void Manager::show_Info()
{cout << "序号:" << setw(2) << setfill('0') << m_id<< "\t姓名:" << m_name<< "\t岗位:" << get_Postname()<< "\t岗位职责:完成老板交办任务,安排员工的工作" << endl;
}
string Manager::get_Postname()
{return string("经理");
}Employee::Employee(int id, string name, int post)
{m_id = id;m_name = name;m_post = post;
}
void Employee::show_Info()
{cout << "序号:" << setw(2) << setfill('0') << m_id<< "\t姓名:" << m_name<< "\t岗位:" << get_Postname()<< "\t岗位职责:完成经理交办任务" << endl;
}
string Employee::get_Postname()
{return string("员工");
}
workerManager.h——管理类
#pragma once //防止头文件重复包含
#include<iostream> //包含输入输出流头文件
using namespace std;//使用标准命名空间
#include"Worker.h"
#define FILENAME "Worker.txt"//职工管理类
class workerManager
{
public://职工指针数组Worker** ptr_Worker_array;//职工人数int m_count;//文件为空标志bool m_EmptyFile;//编号数组int *indexArray;//构造函数workerManager();//展示菜单函数void Show_Menu();//退出系统void Exit_System();//增加职工void Add_Worker();//显示职工void Show_Worker();//删除职工void Del_Worker();//修改职工void Mod_Worker();//查找职工void Search_Worker();//获得文件中人数int get_count();//保存数据到文件中int save();//查找编号,返回下标int Search_ID();//查找姓名,返回相同姓名职工的个数int Search_Name();//按照编号排序void Sort_ID();//清空文件void Clear_Worker();~workerManager();
};
workerManager.cpp——管理类各种功能实现
#include "workerManager.h"
#include<fstream>
//workerManager构造函数
workerManager::workerManager() {ifstream ifs;ifs.open(FILENAME, ios::in);//1、无文件if (!ifs.is_open()) {cout << "文件不存在" << endl;m_EmptyFile = true;m_count = 0;ptr_Worker_array = NULL;}else {//读取职工数量ifs >> m_count;//2、空文件if (!m_count) {cout << "文件为空" << endl;m_EmptyFile = true;m_count = 0;ptr_Worker_array = NULL;}//3、存在数据else {m_EmptyFile = false;ptr_Worker_array = new Worker*[m_count];Worker* newWorker = NULL;int id = 0, num = 0, IDnum = 0;string name;int post = -1;while (ifs >> id && ifs >> name && ifs >> post) {switch (post) {case BOSS:newWorker = new Boss(id, name, post);break;case MANAGER:newWorker = new Manager(id, name, post);break;case EMPLOYEE:newWorker = new Employee(id, name, post);break;}ptr_Worker_array[num++] = newWorker;}}ifs.close();}
}
//显示主界面
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;
}
//退出系统
void workerManager::Exit_System()
{if (this->save()) {cout << "信息保存成功,欢迎下次使用" << endl;system("pause");exit(0);}else {cout << "信息保存失败,请重新保存" << endl;}
}
//添加职工
void workerManager::Add_Worker()
{int newWorker = 0;cout << "请输入添加职工数量:" << endl;cin >> newWorker;Worker** ptr = new Worker*[m_count + newWorker];if (m_count) {for (int i = 0; i < m_count; i++) {ptr[i] = ptr_Worker_array[i];}delete ptr_Worker_array;}ptr_Worker_array = ptr;int id = -1;string name;int post = -1;Worker *worker = NULL;for (int i = 0; i < newWorker; i++) {cout << "请输入第" << i + 1 << "个职工的编号(输入0返回上级):" << endl;cin >> id;while (true) {if (id < 0) {cout << "输入不合法,请重新输入:" << endl;}else if (id == 0) {return;}else {int j = 0;for (j = 0; j < m_count; j++) {if (id == ptr_Worker_array[j]->m_id) {cout << "编号已被占用,请重新输入:" << endl;cin >> id;break;}}if (j == m_count) {break;}}}cout << "请输入第" << i + 1 << "个职工的姓名:" << endl;cin >> name;cout << "请选择该职工岗位:" << endl;cout << "1.老板" << endl;cout << "2.经理" << endl;cout << "3.员工" << endl;cin >> post;switch (post - 1) {case BOSS:worker = new Boss(id, name, BOSS);break;case MANAGER:worker = new Manager(id, name, MANAGER);break;case EMPLOYEE:worker = new Employee(id, name, EMPLOYEE);break;}ptr_Worker_array[m_count] = worker;m_count++;}if (this->save()) {cout << "成功添加 " << newWorker << " 名职工信息" << endl;m_EmptyFile = false;}
}
//显示职工
void workerManager::Show_Worker()
{if (m_count && !m_EmptyFile) {for (int i = 0; i < m_count; i++) {ptr_Worker_array[i]->show_Info();}}
}
//删除职工
void workerManager::Del_Worker()
{if (m_EmptyFile) {cout << "文件不存在" << endl;}else if (m_count == 0) {cout << "文件为空" << endl;}else {cout << "请输入要删除的职工编号(输入0返回上级):" << endl;int id = 0, i = 0;cin >> id;while (id != ptr_Worker_array[i]->m_id) {if (id < 0) {cout << "输入不合法,请重新输入:" << endl;cin >> id;}else if (id == 0) {return;}else {for (i = 0; i < m_count; i++) {if (id == ptr_Worker_array[i]->m_id) {break;}}if (i == m_count) {cout << "查无此人,请重新输入:" << endl;cin >> id;i = 0;}}}delete ptr_Worker_array[i];ptr_Worker_array[i] = NULL;for (; i < m_count - 1; i++) {ptr_Worker_array[i] = ptr_Worker_array[i + 1];}m_count--;if (m_count == 0) m_EmptyFile = true;if (this->save()) {cout << "删除成功" << endl;}}
}
//修改职工
void workerManager::Mod_Worker()
{if (m_EmptyFile) {cout << "文件不存在" << endl;}else if (m_count == 0) {cout << "文件为空" << endl;}else {cout << "请输入要修改的职工编号(输入0返回上级):" << endl;int id = 0, i = 0;cin >> id;while (id != ptr_Worker_array[i]->m_id) {if (id < 0) {cout << "输入不合法,请重新输入:" << endl;cin >> id;}else if (id == 0) {return;}else {for (i = 0; i < m_count; i++) {if (id == ptr_Worker_array[i]->m_id) {break;}}if (i == m_count) {cout << "查无此人,请重新输入:" << endl;cin >> id;i = 0;}}}int newID = 0;string newName;int newPost = -1;cout << "请输入新编号:" << endl;cin >> newID;while (true) {if (newID <= 0) {cout << "输入不合法,请重新输入:" << endl;cin >> newID;}else {int j = 0;for (j = 0; j < m_count; j++) {if (newID == ptr_Worker_array[j]->m_id&&i != j) {cout << "编号已被占用,请重新输入:" << endl;cin >> newID;break;}}if (j == m_count) {break;}}}cout << "请输入新姓名:" << endl;cin >> newName;cout << "请选择职工岗位:" << endl;cout << "1.老板" << endl;cout << "2.经理" << endl;cout << "3.员工" << endl;cin >> newPost;delete ptr_Worker_array[i];ptr_Worker_array[i] = NULL;switch (newPost - 1) {case BOSS:ptr_Worker_array[i] = new Boss(newID, newName, BOSS);break;case MANAGER:ptr_Worker_array[i] = new Manager(newID, newName, MANAGER);break;case EMPLOYEE:ptr_Worker_array[i] = new Employee(newID, newName, EMPLOYEE);break;}if (save()) {cout << "修改成功" << endl;} }
}void workerManager::Search_Worker()
{cout << "请选择查找条件(输入0返回上级):" << endl;cout << "1.职工编号" << endl;cout << "2.职工姓名" << endl;int choice = 0;cin >> choice;while (choice) {if (choice == 1) {int index = Search_ID();if(index>-1){ptr_Worker_array[index]->show_Info();}system("pause");system("cls");Show_Menu();cout << "请选择查找条件(输入0返回上级):" << endl;cout << "1.职工编号" << endl;cout << "2.职工姓名" << endl;cin >> choice;}else if (choice == 2) {int cnt = Search_Name();if (cnt>0) {for (int i = 0; i < cnt; i++) {ptr_Worker_array[indexArray[i]]->show_Info();}delete[] indexArray;indexArray = NULL;}system("pause");system("cls");Show_Menu();cout << "请选择查找条件(输入0返回上级):" << endl;cout << "1.职工编号" << endl;cout << "2.职工姓名" << endl;cin >> choice;}else {cout << "输入不合法,请重新输入:" << endl;cin >> choice;}}
}int workerManager::get_count()
{int cnt = 0;ifstream ifs;ifs.open(FILENAME, ios::in);if (ifs.is_open()) {ifs >> cnt;ifs.close();}return cnt;
}int workerManager::save()
{int res = 1;ofstream ofs;ofs.open(FILENAME, ios::out);if (ofs.is_open()) {ofs << m_count << endl;for (int i = 0; i < m_count; i++) {ofs << ptr_Worker_array[i]->m_id << " "<< ptr_Worker_array[i]->m_name << " "<< ptr_Worker_array[i]->m_post << endl;}ofs.close();}else {res = 0;}return res;
}int workerManager::Search_ID()
{cout << "请输入要查找的编号(输入0返回上级):" << endl;int id = -1, res = -1;cin >> id;if (id == 0) res = -2;while (id) {if (id < 0) {cout << "输入不合法,请重新输入:" << endl;cin >> id;}else {for (int i = 0; i < m_count; i++) {if (id == ptr_Worker_array[i]->m_id) {res = i;id = 0;break;}if (i == m_count - 1 && res == -1) {cout << "查无此人,请重新输入:" << endl;cin >> id;}}}}return res;
}int workerManager::Search_Name()
{int cnt = 0;indexArray = new int[m_count];cout << "请输入要查找的姓名(输入0返回上级):" << endl;string name;cin >> name;while (name != "0") {if (cnt) {break;}else {for (int i = 0; i < m_count; i++) {if (name == ptr_Worker_array[i]->m_name) {indexArray[cnt++] = i;}if (i == m_count - 1 && cnt == 0) {system("pause");cout << "查无此人,请重新输入:" << endl;cin >> name;}}}}return cnt;
}void workerManager::Sort_ID()
{for (int i = 0; i < m_count - 1; i++) {for (int j = i + 1; j < m_count; j++) {if (ptr_Worker_array[i]->m_id > ptr_Worker_array[j]->m_id) {Worker* ptemp = ptr_Worker_array[i];ptr_Worker_array[i] = ptr_Worker_array[j];ptr_Worker_array[j] = ptemp;}}}cout << "排序成功" << endl;
}void workerManager::Clear_Worker()
{if (m_count) {for (int i = 0; i < m_count; i++) {if (ptr_Worker_array[i])delete ptr_Worker_array[i];ptr_Worker_array[i] = NULL;}m_count = 0;}delete[] ptr_Worker_array;ptr_Worker_array = NULL;delete[] indexArray;indexArray = NULL;if (save()) {cout << "清空文件成功" << endl;}
}workerManager::~workerManager() {if (m_count) {for (int i = 0; i < m_count; i++) {if (ptr_Worker_array[i])delete ptr_Worker_array[i];ptr_Worker_array[i] = NULL;}}delete[] ptr_Worker_array;ptr_Worker_array = NULL;delete[] indexArray;indexArray = NULL;
}