C++多态--简易职工管理系统

C++多态

哔哩哔哩:https://www.bilibili.com/video/BV1et411b73Z?p=138&spm_id_from=pageDriver
在这里插入图片描述

主函数

#include<iostream>
#include <csignal>
 #ifdef WIN32
 #include <windows.h>
 #else
 #include <unistd.h>
 #endif
#include "wokerSMS.h"
using namespace std;
extern void clear()//清屏函数
{
#if defined(_WIN32)
	system("pause");
	system("cls");
#else 
	// char buf[1024]={0};
	std::cout << "请输入回车键继续……" << std::endl;
	// fgets(buf,1024,stdin);
	char c;
	std::cin.get();
	while ((c = getchar()) != '\n' && c != EOF);
	system("clear");
#endif
}
void signalHandler(int signum)
{
	std::cout<<"Inttrrupt signal(" << signum <<") received."<<std::endl;
	//清理关闭 终止程序
	exit(signum);
}

// void test()
// {
// 	Staff * worker = NULL;
// 	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;
// }

int main()
{
	// test();
	//注册信号 SIGINT 和信号处理程序
	signal(SIGINT, signalHandler);
    SMS ws;
	int choice = 0;
	while (true)
	{
		//展示菜单
    	ws.showMenu();
		cout << "请输入您的选择:" << endl;
		cin >> choice;

		switch (choice)
		{
		case 0: //退出系统
			ws.exitSystem();
			break;
		case 1: //添加职工
			ws.Add_Emp();
			break;
		case 2: //显示职工
			ws.Disp_Emp();
			break;
		case 3: //删除职工
			ws.Del_Emp();
			break;
		case 4: //查找职工
			ws.Find_Emp();
			break;
		case 5: //修改职工
			ws.Mod_Emp();
			break;
		case 6: //排序职工
			ws.Sort_Emp();
			break;
		case 7: //清空文件
			ws.Clear_Emp();
			break;
		default:
			system("cls");
			break;
		}
	}
    clear();
    return 0;
}

职工系统类

#pragma once
#include<iostream>
#include<string>
#include<fstream>
#include "Staff.h"
#include "employee.h"
#include "boss.h"
#include "manager.h"
const std::string FILENAME="staff.txt";
extern void clear();
class SMS
{
private:
    //员工数组的 指针
    Staff** m_EmpArray;
    //记录文件中的人数个数
    int m_EmpNum;
    // 标志职工文件是否为空
    bool m_FileisEmpty;

public:
    SMS(/* args */){
        std::ifstream ifs;
        ifs.open(FILENAME, std::ios::in);
        // 文件不存在时
        if (!ifs.is_open())
        {
            std::cout<<"文件不存在" << std::endl;
            m_EmpNum = 0;
            m_EmpArray = nullptr;
            m_FileisEmpty = true;
            ifs.close();
            return;
        }
        // 文件存在为空时
        char ch;
        ifs >> ch;
        if (ifs.eof())
        {
            std::cout<<"文件为空"<<std::endl;
            m_EmpNum = 0;
            m_EmpArray = nullptr;
            m_FileisEmpty = true;
            ifs.close();
            return;
        }
        //文件存在且不为空
        int num = this->get_EmpNum();
        std::cout<<"职工人数为:"<<num<<std::endl;
        this->m_EmpNum = num;
        this->m_EmpArray = new Staff*[this->m_EmpNum];
        init_Emp();
    };
    ~SMS(){
        if (this->m_EmpArray != nullptr)
        {
            for (size_t i = 0; i < this->m_EmpNum; i++)
            {
                if (this->m_EmpArray[i] !=nullptr)
                {
                    delete this->m_EmpArray[i];
                }    
            }
            delete[] this->m_EmpArray;
            this->m_EmpArray = nullptr;
        }
        
    };
    //显示菜单
    void showMenu() const;
    // 退出系统
    void exitSystem();
    // 添加员工
    void Add_Emp();
    // 显示员工
    void Disp_Emp() const;
    // 保存文件
    void Save();
    // 读取文件
    void Read();
    // 统计文件中的人数
    int get_EmpNum();
    // 读取文件中员工 初始化 员工数组的 指针
    void init_Emp();
    // 删除职工
    void Del_Emp();
    // 按编号查找职工
    int Find_Emp_Id(int, int begin=0);
    // 按姓名查找职工
    int Find_Emp_Name(std::string, int begin=0);
    //修改员工
    void Mod_Emp();
    //查找职工
    void Find_Emp();
    //按职工编号排序
    void Sort_Emp();
    //清空文件
    void Clear_Emp();
};
#include<memory>
#include "wokerSMS.h"

using namespace std;


void SMS::showMenu(/* args */)const
{
    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 SMS::exitSystem()
{
	cout<<"欢迎下次使用"<<endl;
	exit(0);
}

void SMS::Add_Emp()
{
	cout<<"input num of staff to add"<<endl;
	int addNum = 0;
	cin >> addNum;
	if (addNum > 0)
	{
		//开辟新空间
		int newSize = this->m_EmpNum +  addNum;
		Staff ** newSpace = new Staff*[newSize];
		//将原空间的内容放到新空间
		if (this->m_EmpArray != nullptr)
		{
			for (size_t i = 0; i < this->m_EmpNum; i++)
			{
				newSpace[i] = this->m_EmpArray[i];
			}
		}
		//添加新员工
		for (size_t i = 0; i < addNum; i++)
		{
			int id;
			string name;
			int did;
			cout << "请输入第 " << i + 1 << " 个新职工编号:" << endl;
			while(cin >> id)
			{
				if (Find_Emp_Id(id)==-1)
				{
					break;
				}
				cout<<"该Id已存在,请重新输入:"<<endl;
			}
			cout << "请输入第 " << i + 1 << " 个新职工姓名:" << endl;
			cin >> name;
			cout << "请选择该职工的岗位:" << endl;
			cout << "1、普通职工" << endl;
			cout << "2、经理" << endl;
			cout << "3、老板" << endl;
			cin >> did;

			Staff * addemp = nullptr;
			switch (did)
			{
			// case 1:
			// 	newSpace[i+this->m_EmpNum] = new Employee(id, name, 1);
			// 	break;
			// case 2:
			// 	newSpace[i+this->m_EmpNum] = new Manager(id, name, 2);
			// 	break;
			// case 3:
			// 	newSpace[i+this->m_EmpNum] = new Boss(id, name, 3);
			// 	break;
			case 1:
				addemp = new Employee(id, name, 1);
				break;
			case 2:
				addemp = new Manager(id, name, 2);
				break;
			case 3:
				addemp = new Boss(id, name, 3);
				break;
			default:
				break;
			}//end switch
			//将创建职工职责 ,保存到数组中	
			newSpace[i+this->m_EmpNum] = addemp;
		}//end for	
		//释放原来的空间
		delete[] this->m_EmpArray;
		// 指针指向新空间
		this->m_EmpArray = newSpace;
		// 跟新员工个数
		this->m_EmpNum = newSize;
		// 更新职工不为空
		this->m_FileisEmpty=false;
		//保存到本地文件
		this->Save();
		// 打印提示信息
		cout<<"添加完毕!"<<endl;
	}//end if
	else
	{
		cout<<"bad input"<<endl;
	}
	clear();
}

void SMS::Disp_Emp() const
{
	if (this->m_EmpNum <=0)
	{
		cout<<"文件不存在或记录为空"<<endl;
		clear();
		return;
	}
	
	for (size_t i = 0; i < this->m_EmpNum; i++)
	{
		this->m_EmpArray[i]->showInfo();
	}
	clear();
}

void SMS::Save()
{
	// ofstream saveFile(FILENAME, ios::out);
	// for (size_t i = 0; i < this->m_EmpNum; i++)
	// {
	// 	saveFile <<this->m_EmpArray[i]->m_Id<<" "
	// 			<<this->m_EmpArray[i]->m_Name<<" "
	// 			<<this->m_EmpArray[i]->m_DeptId<<endl;
	// }
	// saveFile.close();
	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();
}

int SMS::get_EmpNum()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	
	int id;
	string name;
	int did;

	int num = 0;
	while (ifs >>id && ifs>>name && ifs>>did)
	{
		++num;
	}
	ifs.close();
	return num;
}

void SMS::init_Emp()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	
	int id;
	string name;
	int did;

	int num = 0;
	while (ifs >>id && ifs>>name && ifs>>did)
	{
		Staff * staff = nullptr;
		if (did == 1)
		{
			staff = new Employee(id, name, 1);
		}
		else if (did == 2)
		{
			staff = new Manager(id, name, 2);
		}
		else
		{
			staff = new Boss(id, name, 3);
		}
		this->m_EmpArray[num]=staff;
		++num;
	}
	ifs.close();

}
void SMS::Del_Emp()
{
	cout<<"输入删除员工的工号:";
	int del_id,index;
	cin>>del_id;
	if (this->m_EmpNum==0)
	{
		cout<<"职工数量为0,无法删除"<<endl;
		return;
	}
	index = Find_Emp_Id(del_id);
	if (index == -1)
	{
		cout<<"无该编号的员工,无法删除"<<endl;
		return;
	}
	for (size_t i = index; i < this->m_EmpNum; i++)
	{
		this->m_EmpArray[i]=this->m_EmpArray[i+1];
	}
	this->m_EmpNum--;
	clear();
}

int SMS::Find_Emp_Id(int id, int begin)
{
	for (size_t i = 0; i < this->m_EmpNum; i++)
	{
		if (this->m_EmpArray[i]->m_Id == id)
		{
			return i;
		}	
	}
	return -1;
}

int SMS::Find_Emp_Name(string name, int begin)
{
	for (size_t i = 0; i < this->m_EmpNum; i++)
	{
		if (this->m_EmpArray[i]->m_Name == name)
		{
			return i;
		}	
	}
	return -1;
}

void SMS::Mod_Emp()
{
	if (this->m_FileisEmpty)
	{
		cout<< "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout<< "请输入修改的编号:"<< endl;
		int id;
		cin >> id;
		int index = this->Find_Emp_Id(id);
		if (index!=-1)
		{
			cout<<"查到该员工的信息:"<<endl;
			this->m_EmpArray[index]->showInfo();
			delete this->m_EmpArray[index];
			this->m_EmpArray[index] = nullptr;

			int id=0;
			string name="";
			int did=0;
			cout << "请输入修改后的职工编号:" << endl;
			cin >> id;
			cout << "请输入修改后的姓名:" << endl;
			cin >> name;
			cout << "请选择修改后的岗位:" << endl;
			cout << "1、普通职工" << endl;
			cout << "2、经理" << endl;
			cout << "3、老板" << endl;
			cin >> did;

			Staff * addemp = nullptr;
			switch (did)
			{
			case 1:
				addemp = new Employee(id, name, 1);
				break;
			case 2:
				addemp = new Manager(id, name, 2);
				break;
			case 3:
				addemp = new Boss(id, name, 3);
				break;
			default:
				break;
			}//end switch

			//将修改的职工 ,保存到数组中	
			this->m_EmpArray[index] = addemp;
			// 保存到文件中
			this->Save();
			cout<<"修改完成~"<<endl;

		}
		else
		{
			cout<<"查无此人"<<endl;
		}
		
	}
	clear();
}

void SMS::Find_Emp()
{
	if (this->m_FileisEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入查找的方式:" << endl;
		cout << "1、按职工编号查找" << endl;
		cout << "2、按姓名查找" << endl;

		int select = 0;
		cin >> select;


		if (select == 1) //按职工号查找
		{
			int id;
			cout << "请输入查找的职工编号:" << endl;
			cin >> id;

			int ret = Find_Emp_Id(id);
			if (ret != -1)
			{
				cout << "查找成功!该职工信息如下:" << endl;
				this->m_EmpArray[ret]->showInfo();
			}
			else
			{
				cout << "查找失败,查无此人" << endl;
			}
		}
		else if (select == 2) //按职工号查找
		{
			string name;
			cout << "请输入查找的职工编号:" << endl;
			cin >> name;

			int ret = Find_Emp_Name(name);
			if (ret != -1)
			{
				cout << "查找成功!该职工信息如下:" << endl;
				this->m_EmpArray[ret]->showInfo();
			}
			else
			{
				cout << "查找失败,查无此人" << endl;
			}
		}
		else
		{
			cout << "输入选项有误" << endl;
		}
	}
	clear();	
}

void SMS::Sort_Emp()
{
	if (this->m_FileisEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout<<"请输入排序方式:"<<endl;
		cout<<"1:按职工进行升序"<<endl;
		cout<<"2:按职工进行升降序"<<endl;

		int select =0;
		cin >> select;

		for (size_t i = 0; i < this->m_EmpNum-1; i++)
		{
			for (size_t j = 0; j < this->m_EmpNum-1-i; j++)
			{
				if (select==1)
				{
					//升序
					if (this->m_EmpArray[j]->m_Id > this->m_EmpArray[j+1]->m_Id)
					{
						Staff * temp = m_EmpArray[j];
						m_EmpArray[j] = m_EmpArray[j+1];
						m_EmpArray[j+1] = temp;
					}
				}
				else //if (select==2)
				{
					//jiang序
					if (this->m_EmpArray[j]->m_Id < this->m_EmpArray[j+1]->m_Id)
					{
						Staff * temp = m_EmpArray[j];
						m_EmpArray[j] = m_EmpArray[j+1];
						m_EmpArray[j+1] = temp;
					}
				}	
			}	
		}
		cout<< "排序后为:"<<endl;
		Save();
		this->Disp_Emp();
	}
}

void SMS::Clear_Emp()
{
	if (this->m_FileisEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout<<"请确认是否删除:(y/n)"<<endl;
		char choice;
		cin>>choice;
		if (choice='y')	
		{
			// 打开模式 ios::trunc 如果存在 删除文件并重新创建
			ofstream ofs(FILENAME, ios::trunc);
			ofs.close();

			if (this->m_EmpArray != nullptr)
			{
				for (size_t i = 0; i < this->m_EmpNum; i++)
				{
					if (this->m_EmpArray[i] != nullptr)
					{
						delete this->m_EmpArray[i];
					}
				}
				this->m_EmpNum = 0;
				delete[] this->m_EmpArray;
				this->m_FileisEmpty = true;
				this->m_EmpArray = nullptr;
			}
			cout<<"清空成功!";
		}
	}
	clear();
}

职工类

#pragma once
#include<iostream>
#include<string>
#include<fstream>
class Staff
{
private:
    /* data */
public:
    Staff(/* args */){
        std::cout<<"Staff()"<<std::endl;
    };
    virtual ~Staff(){
        std::cout<<"~Staff()"<<std::endl;
    };
    int m_Id;   //职工编号
    std::string m_Name;   //职工姓名
    int m_DeptId;

    //显示个人信息
    virtual void showInfo() = 0;
    //返回岗位信息
    virtual std::string getDeptName() = 0;
};

普通职工类

#pragma once
#include "Staff.h"

class Employee :public Staff
{
private:
    /* data */
public:
    Employee(int id=0, std::string name=" ", int did=0){
        m_Id=id;
        m_Name = name;
        m_DeptId = did;
        std::cout<<"Employee()"<<std::endl;
    }
    ~Employee(){
        std::cout<<"~Employee()"<<std::endl;
    };
    void showInfo() override
    {
        std::cout<<"职工编号:"<<m_Id
                <<"\t姓名:"<<m_Name
                <<"\t岗位:"<<getDeptName()
                <<"\t岗位职责:完成上级交给的任务"<<std::endl;
    }
    std::string getDeptName() override
    {
        return std::string("员工");
    }
};

经理类

#pragma once
#include "Staff.h"

class Manager :public Staff
{
private:
    /* data */
public:
    Manager(int id=0, std::string name=" ", int did=0){
        m_Id=id;
        m_Name = name;
        m_DeptId = did;
        std::cout<<"Manager()"<<std::endl;
    }
    ~Manager(){
        std::cout<<"~Manager()"<<std::endl;

    };
    void showInfo() override
    {
        std::cout<<"职工编号:"<<m_Id
                <<"\t姓名:"<<m_Name
                <<"\t岗位:"<<getDeptName()
                <<"\t岗位职责:完成老板交给的任务,给员工派任务。"<<std::endl;
    }
    std::string getDeptName() override
    {
        return std::string("经理");
    }
};

老板类

#pragma once
#include "Staff.h"

class Boss :public Staff
{
private:
    /* data */
public:
    Boss(int id=0, std::string name=" ", int did=0){
        m_Id=id;
        m_Name = name;
        m_DeptId = did;
        std::cout<<"Boss()"<<std::endl;
    }
    ~Boss(){
        std::cout<<"~Boss()"<<std::endl;
    };
    void showInfo() override
    {
        std::cout<<"职工编号:"<<m_Id
                <<"\t姓名:"<<m_Name
                <<"\t岗位:"<<getDeptName()
                <<"\t岗位职责:管理公司事务。"<<std::endl;
    }
    std::string getDeptName() override
    {
        return std::string("老板");
    }
};

总结

1、职工数据 用职工类Staff的指针数组存储,可以存自己或子类的指针,直接用“this->m_EmpArray[i]->showInfo();”实现多态;加override显示该成员函数为重写的
2、使用指针数组练习指针操作、new、delete等;new一个指针数组Staff ** newSpace = new Staff*[newSize];
3、读取TXT的一种方法
在这里插入图片描述
在这里插入图片描述
4、代码交互的地方较多,输入校验过少。
5、增加信号处理 signal(SIGINT, signalHandler);(捕获到Ctrl+C终止程序)。
6、增加预编译,判断运行环境。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值