目录
前言
职工管理系统是本人刚学习完C++封装、继承、多态的特性后利用其编写的第一个项目程序,该系统不仅包含了基本的增删改查,同时将之前通讯录管理系统上做了文件读写方面的操作,成功实现了控制台和项目解决方案目录的txt文档互联,其中涉及到老板、经理、员工都设定为职工Worker类的子类,利用多态的特性实现了创建新职工时可以直接采用父类指针指向子类对象的方式创建,大大提高了代码复用性,有效避免冗杂代码的呈现。
当然,该程序可以通过添加异常处理模块以提升代码健壮性,异常处理的模块化操作欢迎参考本人博文:http://t.csdn.cn/m17Re
一、项目要求
我们需要实现对公司员工基本信息进行统计,包含职工编号、职工姓名、岗位、岗位职责,利用C++多态的特性实现代码复用,项目打开时需要首先进行初始化读文件写入控制台实现初始化,接着进入程序后按键入编号可以实现对员工信息的基本的增删改查操作等。
二、代码演示
首先给出职工抽象类实现的头文件,以便老板、经理、员工都可以通过继承职工类实现多态:
1. worker.h
#pragma once
#include<iostream>
using namespace std;
//职工抽象类
class Worker
{
public:
//显示个人信息
virtual void showinfo() = 0;
//获取岗位名称
virtual string getdeptid() = 0;
//职工编号
int m_id;
//职工姓名
string m_name;
//部门编号
string m_deptid;
};
接着给出老板、经理、员工的分别类存储实现:
Boss类:
2. boss.h
头文件负责类中函数声明:
#pragma once
//老板
#include<iostream>
#include"worker.h"
using namespace std;
class Boss :public Worker
{
public:
//构造函数
Boss(int id, string name, string did);
//显示个人信息
virtual void showinfo();
//获取岗位名称
virtual string getdeptid();
};
3. boss.cpp
cpp文件负责具体实现函数内部操作:
#include<iostream>
//老板
#include"boss.h"
using namespace std;
//构造函数
Boss::Boss(int id, string name, string did)
{
this->m_id = id;
this->m_name = name;
this->m_deptid = did;
}
//显示个人信息
void Boss::showinfo()
{
cout << "职工编号: " << m_id << "\t"
<< "职工姓名: " << m_name << "\t"
<< "岗位: " << getdeptid() << "\t"
<< "岗位职责: 管理公司所有事务" << endl;
}
//获取岗位名称
string Boss::getdeptid()
{
return string("老板");
}
manager(经理)类:
4. manager.h
#pragma once
//经理
#include<iostream>
#include"worker.h"
using namespace std;
class Manager :public Worker
{
public:
//构造函数
Manager(int id, string name, string did);
//显示个人信息
virtual void showinfo();
//获取岗位名称
virtual string getdeptid();
};
5. manager.cpp
#include<iostream>
//经理
#include"manager.h"
using namespace std;
//构造函数
Manager::Manager(int id, string name, string did)
{
this->m_id = id;
this->m_name = name;
this->m_deptid = did;
}
//显示个人信息
void Manager::showinfo()
{
cout << "职工编号: " << m_id << "\t"
<< "职工姓名: " << m_name << "\t"
<< "岗位: " << getdeptid() << "\t"
<< "岗位职责: 完成老板交给的任务,管理员工" << endl;
}
//获取岗位名称
string Manager::getdeptid()
{
return string("经理");
}
employee(员工)类:
6. employee.h
#pragma once
//普通职工
#include<iostream>
#include"worker.h"
using namespace std;
class Employee :public Worker
{
public:
//构造函数
Employee(int id, string name, string did);
//显示个人信息
virtual void showinfo();
//获取岗位名称
virtual string getdeptid();
};
7. employee.cpp
//普通职工
#include<iostream>
#include"employee.h"
using namespace std;
//构造函数
Employee::Employee(int id,string name,string did)
{
this->m_id = id;
this->m_name = name;
this->m_deptid = did;
}
//显示个人信息
void Employee::showinfo()
{
cout << "职工编号: " << m_id<<"\t"
<<"职工姓名: " <<m_name<<"\t"
<<"岗位: "<<getdeptid() <<"\t"
<<"岗位职责: 完成经理交给的任务" << endl;
}
//获取岗位名称
string Employee::getdeptid()
{
return string("员工");
}
现在已经有这些方便的类用于构建成员及存储个人信息,接下来就到正式分别定义实现增删改查操作的函数:
8. workermanager.h
#pragma once //防止头文件重复包含
#include<iostream> //包含输入输出流头文件
#include<fstream>
#define FILENAME "empfile.txt"
#include"worker.h"
#include"employee.h"
#include"manager.h"
#include"boss.h"
using namespace std; //使用标准命名空间
class Workermanager
{
public:
Workermanager();
//菜单界面
void Showmenu();
//退出系统
void Exitsystem();
//记录职工人数
int m_empnum;
//职工数组指针
Worker** m_empArray;
//添加职工
void Add_emp();
//保存文件
void save();
//判断文件是否为空 标志
bool m_fileisempty;
//统计文件中人数
int get_empnum();
//初始化员工
void init_emp();
//显示职工
void show_emp();
//删除职工
void del_emp();
//判断职工是否存在(存在返回数组中位置,不存在返回-1)
int isexist(int id);
//修改职工
void mod_emp();
//判断职工编号是否重复
void isidsame();
//查找职工
void find_emp();
//按照编号排序
void sort_emp();
void upsort();//升序
void downsort();//降序
//清空文件
void clean_file();
~Workermanager();
};
9. workermanager.cpp
#include<iostream>
#include<cstdlib>
#include"workermanager.h"
#include"worker.h"
using namespace std;
Workermanager::Workermanager()
{
//1.文件不存在
ifstream ifs;
ifs.open(FILENAME, ios::in);
if (!ifs.is_open())
{
cout << "*** 文件不存在 ***" << endl;
//初始化人数
this->m_empnum = 0;
//初始化指针
this->m_empArray = NULL;
//初始化判断文件是否为空 标识
this->m_fileisempty = true;
ifs.close();
return;
}
//2.文件存在,数据为空
char ch;
ifs >> ch;
if (ifs.eof())
{
//文件为空
cout << "文件为空" << endl;
//初始化人数
this->m_empnum = 0;
//初始化指针
this->m_empArray = NULL;
//初始化判断文件是否为空 标识
this->m_fileisempty = true;
ifs.close();
return;
}
//3.文件数据存在
int num = this->get_empnum();
if (num != 0)
{
cout << "初始化成功 *** 人数为:" << num << endl;
}
this->m_empnum = num;
//开辟空间
this->m_empArray = new Worker * [this->m_empnum];
//将文件中数据存到数组中
this->init_emp();
for (int i = 0; i < this->m_empnum; i++)
{
cout << "职工编号:" << this->m_empArray[i]->m_id << endl;
}
}
//展示菜单
void Workermanager::Showmenu()
{
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;
}
//退出系统
void Workermanager::Exitsystem()
{
cout << "***** 欢迎下次使用 *****" << endl;
system("pause");
exit(0);
}
//判断职工编号是否重复
void Workermanager::isidsame()
{
int id = 0;
while (true)
{
cin >> id;
int j = 0;
int temp = 0;
while (j < this->m_empnum)
{
temp = j;
if (id == m_empArray[j]->m_id)
{
cout << "*** 输入编号已存在,请重新输入 ***" << endl;
break;
}
j++;
}
if (id != m_empArray[temp]->m_id)
{
cout << "***** 编号录入成功 *****" << endl;
break;
}
}
}
//添加职工
void Workermanager::Add_emp()
{
cout << "请输入添加职工数量: " << endl;
int addnum = 0; //记录用户的输入数量
cin >> addnum;
while (true)
{
if (addnum > 0)
{
//计算新空间大小
int newsize = this->m_empnum + addnum; //新空间人数=原记录人数+新增人数
//开辟新空间
Worker** newspace = new Worker * [newsize * sizeof(Worker)];
//将原来空间下数据拷贝到新空间下
if (this->m_empArray != NULL)
{
for (int i = 0; i < this->m_empnum; i++)
{
newspace[i] = this->m_empArray[i];
}
}
//批量添加新数据
int id = 0;
string name = "";
string deptid = "";
for (int i = 0; i < addnum; i++)
{
cout << "请输入第" << i + 1 << "个职工编号:" << endl;
//判断职工编号是否重复
isidsame();
cout << "请输入第" << i + 1 << "个职工姓名:" << endl;
cin >> name;
cout << "请输入第" << i + 1 << "个职工岗位:" << endl;
cout << "1.普通员工" << endl;
cout << "2.经理" << endl;
cout << "3.老板" << endl;
Worker* worker = NULL;
//想要实现 输入错误报告后重新转回输入再判断,需要将输入cin放在循环首部 无else “请重新输入”放在if判断后循环末尾
while (true)
{
cin >> deptid;
if (deptid == "1")
{
worker = new Employee(id, name, "1");
//将创建的职工指针保存到数组中
newspace[this->m_empnum + i] = worker;
break;
}
else if (deptid == "2")
{
worker = new Manager(id, name, "2");
newspace[this->m_empnum + i] = worker;
break;
}
else if (deptid == "3")
{
worker = new Boss(id, name, "3");
newspace[this->m_empnum + i] = worker;
break;
}
cout << "*** 请输入1-3数字 ***" << endl;
}
}
//释放原有空间
delete[] this->m_empArray;
//更改新空间指向
this->m_empArray = newspace;
//更新职工人数
this->m_empnum = newsize;
//更新职工不为空标志
this->m_fileisempty = false;
//成功添加后 保存到文件中
this->save();
cout << "*** 成功添加" << addnum << "名新职工 ***" << endl;
break;
}
else
{
cout << "*** 输入有误,请重新输入 ***" << endl;
break;
}
}
//按任意键后 清屏并返回上级目录
system("pause");
system("cls");
}
//保存文件
void Workermanager::save()
{
ofstream ofs;
ofs.open(FILENAME, ios::out); //用输出的方式打开文件 —— 写文件
//if (this->m_empnum > 0)
//{
// ofs << "编号" << "\t"
// << "姓名" << "\t"
// << "部门" << endl;
//}
//将每个人数据写入到文件中
for (int i = 0; i < this->m_empnum; i++)
{
ofs << this->m_empArray[i]->m_id << " \t "
<< this->m_empArray[i]->m_name << " \t "
<< this->m_empArray[i]->m_deptid << endl;
}
ofs.close();
}
//统计文件中人数
int Workermanager::get_empnum()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);//打开文件,读文件
string name;
string did;
int num = 0;
int id;
while (ifs >> id && ifs >> name && ifs >> did)
{
num++;
}
//while (ifs.get(c))
//{
// if (c == '\n') //一行一个职工
// num++; //行数加 1
//}
//if (num > 0)
//{
// num--; //减去抬头标注行
//}
return num;
}
//初始化员工
void Workermanager::init_emp()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int id;
string name;
string did;
int line = get_empnum();
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
{
worker = new Boss(id, name, did);
}
this->m_empArray[index] = worker;
index++;
}
ifs.close();
}
//显示员工
void Workermanager::show_emp()
{
if (m_fileisempty)
{
cout << "*** 该文件不存在或数据为空 ***" << endl;
}
else
{
for (int i = 0; i < m_empnum; i++)
{
this->m_empArray[i]->showinfo();
}
}
system("pause");
system("cls");
}
//删除职工
void Workermanager::del_emp()
{
if (this->m_fileisempty)
{
cout << "*** 文件不存在或记录为空 ***" << endl;
}
else
{
int id = 0;
cout << "请输入要删除职工的对应编号:" << endl;
cin >> id;
if (isexist(id) != -1)
{
for (int i = isexist(id); i < m_empnum - 1; i++)
{
this->m_empArray[i] = this->m_empArray[i + 1];
}
//更新人数
m_empnum--;
if (m_empnum == 0)
{
m_fileisempty = true;
}
//数据同步更新到文件
this->save();
cout << "***** 该职工已成功删除 *****" << endl;
}
else
{
cout << "*** 删除失败,查无此人 ***" << endl;
}
}
system("pause");
system("cls");
}
//判断职工是否存在(存在返回数组中位置,不存在返回-1)
int Workermanager::isexist(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->m_fileisempty)
{
cout << "*** 文件不存在或数据为空 ***" << endl;
}
else
{
cout << "请输入想要修改的职工对应编号:" << endl;
int id;
cin >> id;
if (isexist(id) != -1)
{
delete this->m_empArray[isexist(id)];
int newid = 0;
string newname = "";
string newdid = "";
cout << "*** 查找成功 ***" << endl;
cout << "请输入新职工编号:" << endl;
cin >> newid;
cout << "请输入新职工姓名:" << endl;
cin >> newname;
cout << "请输入新职工部门:" << endl;
cout << "1.普通员工" << endl;
cout << "2.经理" << endl;
cout << "3.老板" << endl;
Worker* worker = NULL;
while (true)
{
cin >> newdid;
if (newdid == "1")
{
worker = new Employee(newid, newname, "1");
//将创建的职工指针保存到数组中
m_empArray[isexist(id)] = worker;
break;
}
else if (newdid == "2")
{
worker = new Manager(newid, newname, "2");
m_empArray[isexist(id)] = worker;
break;
}
else if (newdid == "3")
{
worker = new Boss(newid, newname, "3");
m_empArray[isexist(id)] = worker;
break;
}
cout << "*** 请输入1-3数字 ***" << endl;
}
//保存到文件中
this->save();
cout << "***** 修改成功 *****" << endl;
}
}
}
//查找职工
void Workermanager::find_emp()
{
if (this->m_fileisempty)
{
cout << "*** 文件不存在或数据为空 ***" << endl;
}
else
{
cout << "*** 请输入查找方式: ***" << endl;
cout << "*** 1.按职工编号查找 ***" << endl;
cout << "*** 2.按职工姓名查找 ***" << endl;
bool flag = false;
string select = "0";
cin >> select;
if (select == "1")
{
//编号
int id;
cout << "请输入查找的职工编号:" << endl;
cin >> id;
int ret = isexist(id);
if (ret != -1)
{
cout << "查找成功,信息如下:" << endl;
this->m_empArray[ret]->showinfo();
flag = true;
}
}
else if (select == "2")
{
//按姓名
string name;
cout << "请输入查找的姓名:" << endl;
cin >> name;
for (int i = 0; i < m_empnum; i++)
{
if (this->m_empArray[i]->m_name == name)
{
cout << "查找成功,职工编号为" << this->m_empArray[i]->m_id
<< "的员工信息如下:" << endl;
//调用查找信息接口
this->m_empArray[i]->showinfo();
flag = true;
}
}
}
if (!flag)
{
cout << "*** 输入有误请重新输入 ***" << endl;
}
}
system("pause");
system("cls");
}
//排序实现
void Workermanager::downsort()
{
for (int i = 0; i < m_empnum; i++)
{
for (int j = i + 1; j < m_empnum; j++)
{
if (m_empArray[j]->m_id > m_empArray[i]->m_id)
{
Worker* temp = m_empArray[j];
m_empArray[j] = m_empArray[i];
m_empArray[i] = temp;
}
}
}
}
void Workermanager::upsort()
{
for (int i = 0; i < m_empnum; i++)
{
for (int j = i + 1; j < m_empnum; j++)
{
if (m_empArray[j]->m_id < m_empArray[i]->m_id)
{
Worker* temp = m_empArray[j];
m_empArray[j] = m_empArray[i];
m_empArray[i] = temp;
}
}
}
}
//按照编号排序
void Workermanager::sort_emp()
{
if (this->m_fileisempty)
{
cout << "*** 文件不存在或记录为空 ***" << endl;
system("pause");
system("cls");
}
else
{
cout << "*** 请选择排序方式:***" << endl;
cout << "*** 1.按升序排列 ***" << endl;
cout << "*** 2.按降序排列 ***" << endl;
int select = 0;
cin >> select;
if (select == 2)
{
downsort();
show_emp();
}
else if (select == 1)
{
upsort();
show_emp();
}
else
{
cout << "*** 输入有误,请重新输入 ***" << endl;
}
//存入文件
this->save();
}
}
//清空文件
void Workermanager::clean_file()
{
cout << "确认清空整个文件吗?" << endl;
cout << "***** 1.确认 *****" << endl;
cout << "***** 2.返回 *****" << endl;
int select = 0;
cin >> select;
if (select == 1)
{
//清空
ofstream ofs(FILENAME, ios::trunc);
ofs.close();
if (this->m_empArray != NULL)
{
//删除堆区每个职工对象
for (int i = 0; i < m_empnum; i++)
{
delete m_empArray[i];
m_empArray[i] = NULL;
}
//删除堆区数组指针
delete[] this->m_empArray;
this->m_empArray = NULL;
this->m_empnum = 0;
this->m_fileisempty = true;
}
cout << "***** 清空成功 *****" << endl;
system("pause");
system("cls");
}
else
{
return;
}
}
Workermanager::~Workermanager()
{
if (this->m_empArray != NULL)
{
for (int i = 0; i < m_empnum; i++)
{
if (this->m_empArray[i] != NULL)
{
delete m_empArray[i];
m_empArray[i] = NULL;
}
}
delete[] this->m_empArray;
this->m_empArray = NULL;
}
}
//完结于 2022.8.28 19:00
最后还有控制调用这些函数的模块,以及好看的界面,将其都最后整合在 main() 函数中:
10. 源.cpp
#include<iostream>
using namespace std;
#include"workermanager.h"
#include"worker.h"
#include"employee.h"
#include"manager.h"
#include"boss.h"
void main()
{
//实例化管理者对象
Workermanager wm;
string choice = "0"; //用户选择
while (true)
{
//调用展示菜单成员函数
wm.Showmenu();
cout << "请输入您的选择" << endl;
cin >> choice;
while (true)
{
if (choice == "0")//退出系统
{
wm.Exitsystem();
break;
}
else if (choice == "1")//增加职工
{
wm.Add_emp();
break;
}
else if (choice == "2")//显示职工
{
wm.show_emp();
break;
}
else if (choice == "3")//删除职工
{
/*cout<<wm.isexist(1)<<endl;*/
wm.del_emp();
break;
}
else if (choice == "4")//修改职工
{
wm.mod_emp();
break;
}
else if (choice == "5")//查找职工
{
wm.find_emp();
break;
}
else if (choice == "6")//排序员工
{
wm.sort_emp();
break;
}
else if (choice == "7")//清空文档
{
wm.clean_file();
break;
}
else
{
system("cls");//清屏
break;
}
}
}
system("pause");
}
三、运行示例
这里出于测试初始化,《 empfile.txt 》文件里已经有部分职工信息:
总结
以下的总结可以直接用于你的课设论文心得部分:
本项目是一个简单的职工管理系统,通过C++的封装、继承和多态的特性实现了代码的复用和灵活性。在项目中,将老板、经理和员工都设定为职工Worker类的子类,利用多态的特性实现了创建新职工时可以直接采用父类指针指向子类对象的方式创建,提高了代码的复用性。
在程序运行时,首先进行初始化,读取文件并将数据写入控制台,实现了程序的初始化功能。然后,可以通过输入职工编号实现对员工信息的基本的增删改查操作。通过封装、继承和多态的特性,实现了对员工信息的灵活管理。
在项目中,还涉及到了文件读写的操作,将项目解决方案目录的txt文档和控制台实现了互联,实现了数据的持久化存储和读取。
通过这个项目,我不仅巩固了C++的封装、继承和多态的知识,还学习了文件读写的操作。同时,通过实际的项目练习,我也深刻理解了代码复用和灵活性的重要性。在以后的项目开发中,我会更加注重代码的复用和灵活性,提高代码的可维护性和可拓展性。
博客文章总结:
希望这篇博客能给读者带来启发和帮助,感谢您的阅读!