基于多态的增删改查

worker.h 这是一个抽象基类,作为借口让其余三个子类接入

class worker
{
public:
    virtual void show_info()=0;
    virtual string get_bumen()=0;
    int id;
    string name;
    int bumen;
};

下面是BOSS.H和BOSS.CPP,员工和经理的cpp,h都类似,这里就是worker虚函数实现的地方。
这样便可以使用多态接入。 我们在定义一个新员工时,不知道他是这三种中的哪种便可以使用worker。

#pragma once
#include "iostream"
#include "string"
#include "worker.h"
using namespace std;


class BOSS:public worker
{
public:
    BOSS(int newid, string newname, int newbumen);
     void show_info();
    string get_bumen();

};
#include "BOSS.h"




void BOSS::show_info()
{
    cout<<"职工编号 "<< this->id
        << " \t职工姓名: " << this->name
        << " \t岗位:" << this->get_bumen()
        << " \t岗位职责:完成公司所有事务" << endl;
}


string BOSS::get_bumen()
{

    return string("大老板");
}
//构造函数
BOSS::BOSS(int newid, std::string newname, int newbumen)
{
    this->id=newid;
    this->name=newname;
    this->bumen=newbumen;
}

这是管理系统的.h

#pragma once
#include "iostream"
#include "string"
#include "worker.h"
#include "jingli.h"
#include "yuangong.h"
#include "BOSS.h"
#include "fstream"
using namespace std;
#define FILENAME "book.txt"



class Management_system
{
public:
    //构造函数
    Management_system();
    //析构函数
    ~Management_system();
    //菜单展示
    void show_menu();
    //退出功能
    void exit_system();
    //添加职工
    void addworker();
    //保存当前职工管理系统中所有人的信息进文件
    void save();
    //得到目前职工人数
    int get_num();
    //文件里有人 就初始化数组把文件里的人搞到数组里来
    void init();
    //显示职工
    void show_all();
    //删除职工
    void cleanone();
    //找到某个职工
    int findone(int id);
    //修改职工
    void modify();
    //查找职工
    void showone();
    //排序职工
    void SORT();
    //清空函数
    void cleanall();

    bool isempty;
    int max_num;
    worker** arry;
};

添加职工功能

如果本来就有职工,那就把原来所有职工中的数据都迁移到现在这个新数组中来。所以需要扩展数组空间

使用了一个worker**[]数组来存放信息,是存放指针的数组

void Management_system::addworker()
{
    cout<<"请输入添加职工的数量:"<<endl;
    int addnum=0;
    cin>>addnum;
    if(addnum>0)
    {
        int newsize=addnum+this->max_num;
        //这里定义一个存放worker*指针的数组,
        worker**newspace=new worker * [newsize];
        //把原有数组中的工作人员复制到新数组中
        if(this->arry!=NULL)
        {
            for(int i=0;i<this->max_num;i++)
            {
                newspace[i]=this->arry[i];
            }
        }
        //接受新输入的工作人员
        for(int i=0;i<addnum;i++)
        {
            int newid;string newname;int newbumen;
            cout << "请输入第 " << i + 1 << " 个新职工编号:" << endl;
            cin >> newid;
            cout << "请输入第 " << i + 1 << " 个新职工姓名:" << endl;
            cin >> newname;
            cout << "请选择该职工的岗位:" << endl;
            cout << "1、普通职工" << endl;
            cout << "2、经理" << endl;
            cout << "3、老板" << endl;
            cin>>newbumen;
            worker*newworker=NULL;
            switch (newbumen)
            {
                case 1: newworker=new yuangong(newid,newname,1);break;
                case 2: newworker=new jingli(newid,newname,2);break;
                case 3: newworker=new BOSS(newid,newname,3);break;
                default: break;
            }
            newspace[i+this->max_num]=newworker;

        }
        //更新管理系统
        delete[] this->arry;  // 释放指针数组
        this->arry=newspace;this->max_num=newsize;
        cout<<"成功添加第"<<addnum<<"位新员工"<<endl;
        this->save();
        this->isempty=0;
    }else
    {
        cout<<"输入有误"<<endl;
    }
    system("pause");
    system("cls");
}

退出功能

void Management_system::exit_system()
{
    cout<<"欢迎下次使用"<<endl;
    system("pause");
    exit(0);
}

写文件

当前数组中的所有元素写入文件中存储

void Management_system::save()
{
    ofstream ofs;
    ofs.open(FILENAME,ios::out);
    if(this->arry!=NULL)
    {
        for(int i=0;i<this->max_num;i++)
        {
            ofs<<this->arry[i]->id<<" "
               <<this->arry[i]->name<<" "
               <<this->arry[i]->bumen<<endl;
        }
    }

    ofs.close();
}

初始化数组

如果文件中本来就有内容,我们需要把他读入进数组方便操作
void Management_system::init() { ifstream ifs; ifs.open(FILENAME,ios::in); int id;string name;int bumen; int index=0; while(ifs>>id&&ifs>>name&&ifs>>bumen) { worker*nw=NULL; switch (bumen) { case 1: nw=new yuangong(id,name,1);break; case 2: nw=new jingli(id,name,2);break; case 3: nw=new BOSS(id,name,3);break; default: break; } this->arry[index++]=nw; } }

获取文件中的人数

int Management_system::get_num()
{
    ifstream ifs;
    ifs.open(FILENAME,ios::in);
    int ans=0;
    int id;string name;int bumen;
    while(ifs>>id&&ifs>>name&&ifs>>bumen)
    {ans++;}
    ifs.close();
    return ans;
}

构造函数

分三种情况,如果文件没有创建, 有文件但是记录为空,文件有记录,那就init把他传入数组
这里有个char ch,ifs>>ch; 意思是定义一个字符,用字符去读取ifs文件中的第一个字符,他会自动跳过空格或者各种控制符
ifs.eof(),意思是判断ifs是不是读到了文件末尾; 如果读一个字符就读到了文件尾那就是空,返回true

Management_system::Management_system()
{
   ifstream ifs;
   ifs.open(FILENAME,ios::in);
   //文件如果未创建
   if(!ifs.is_open()) //检查文件是否成功打开
   {
       cout<<"文件不存在"<<endl;
        this->max_num=0;
        this->isempty=1;
        this->arry=NULL;
       ifs.close();
       return ;
   }
  //文件存在但是为空
  char ch;
   ifs>>ch; //这里是读入一个字符
   if(ifs.eof())
   {
       cout<<"文件为空"<<endl;
       this->max_num=0;
       this->isempty=1;
       this->arry=NULL;
       ifs.close();
       return ;
   }
   //文件存在也有数据
    int num=this->get_num();
   cout<<"职工个数为"<<num<<endl;
   this->max_num=num;
   this->arry=new worker*[num];
   init();
//   for(int i=0;i<this->max_num;i++)
//   {
//       this->arry[i]->show_info();
//   }
}

显示职工

void Management_system::show_all()
{
    if(this->arry==NULL)cout<<"文件不存在或记录为空"<<endl;
    else
    {
        for(int i=0;i<this->max_num;i++)
        {
            this->arry[i]->show_info();
        }
    }
    system("pause");
    system("cls");
}

找到某个职工

int Management_system::findone(int id)
{
    int ans=-1;
    for(int i=0;i<this->max_num;i++)
    {
        if(this->arry[i]->id==id)
        {ans=i;break;}

    }
    return ans;
}

删除职工

void Management_system::cleanone()
{
    if(this->arry==NULL)
    {
        cout<<"文件不存在或记录为空"<<endl;
    }
    else
    {
        cout << "请输入想要删除的职工号:" << endl;
        int id;cin>>id;
        int index=this->findone(id);
        if(index!=-1)
        {
            for(int i=index;i<this->max_num;i++)
            {
                this->arry[i]=this->arry[i+1];
            }
            this->max_num--;
            cout << "删除成功!" << endl;
            this->save();
        }
        else
        {
            cout << "删除失败,未找到该职工" << endl;
        }
    }
}

修改职工

void Management_system::modify()
{
    if(this->arry==NULL)
    {
        cout<<"文件不存在或记录为空"<<endl;
    }else
    {
        cout << "请输入修改职工的编号:" << endl;
        int id;
        cin >> id;
        int index= findone(id);
        if(index!=-1)
        {
            delete this->arry[index];
            int newid;string newname;int newbumen;
            cout << "查到: " << id << "号职工,请输入新职工号: " << endl;
            cin >> newid;
            cout << "请输入新姓名: " << endl;
            cin >> newname;
            cout << "请输入岗位: " << endl;
            cout << "1、普通职工" << endl;
            cout << "2、经理" << endl;
            cout << "3、老板" << endl;
            cin>>newbumen;
            worker*newworker=NULL;
            switch (newbumen)
            {
                case 1: newworker=new yuangong(newid,newname,1);break;
                case 2: newworker=new jingli(newid,newname,2);break;
                case 3: newworker=new BOSS(newid,newname,3);break;
                default: break;
            }
            this->arry[index]=newworker;
            cout << "修改成功!" << endl;
            this->save();

        }else
        {
            cout << "修改失败,查无此人" << endl;
        }

    }
    system("pause");
    system("cls");
}

查找职工

void Management_system::showone()
{
    if(this->arry==NULL)
    {
        cout<<"文件不存在或记录为空"<<endl;
    }else
    {
        cout << "请输入查找的方式:" << endl;
        cout << "1、按职工编号查找" << endl;
        cout << "2、按姓名查找" << endl;
        int sel=0;
        cin>>sel;
        if(sel==1)
        {
            int id;
            cout << "请输入查找的职工编号:" << endl;
            cin >> id;
            int index;
            index= findone(id);
            if(index!=-1)
            {
                cout << "查找成功!该职工信息如下:" << endl;
                this->arry[index]->show_info();
            }else
            {
                cout << "查找失败,查无此人" << endl;
            }
        }else if(sel==2)
        {
                string name;
            cout << "请输入查找的姓名:" << endl;
            cin >> name;
            bool flag=0;
            for(int i=0;i<this->max_num;i++)
            {
                if(name==this->arry[i]->name)
                {
                    flag==1;
                    cout << "查找成功!该职工信息如下:" << endl;
                    this->arry[i]->show_info();
                    break;
                }
            }
            if(flag==0)
            {
                cout << "查找失败,查无此人" << endl;
            }
        }else
        {
            cout << "输入选项有误" << endl;
        }
    }
    system("pause");
    system("cls");
}

排序职工

这里使用了选择排序

void Management_system::SORT()
{
    if(this->arry==NULL)
    {
        cout<<"文件不存在或记录为空"<<endl;
    }else
    {
        cout << "请选择排序方式: " << endl;
        cout << "1、按职工号进行升序" << endl;
        cout << "2、按职工号进行降序" << endl;
        int sel=0;
        cin>>sel;
        for(int i=0;i<this->max_num;i++)
        {
            int minormax=i;
            for(int j=i+1;j<this->max_num;j++)
            {
                if(sel==1)
                {
                    if(this->arry[minormax]->id>this->arry[j]->id)
                    {
                        minormax=j;
                    }
                }else
                {
                    if(this->arry[minormax]->id<this->arry[j]->id)
                    {
                        minormax=j;
                    }
                }
                if(i!=minormax)
                {
                    worker * temp = this->arry[i];
                    this->arry[i]=this->arry[minormax];
                    this->arry[minormax]=temp;
                }
            }
        }
        cout << "排序成功,排序后结果为:" << endl;
        this->save();
        this->show_all();
    }
}

清空职工

trunc 是什么?

truncC++ 文件流(ofstream)的打开模式,完整写法是 ios::trunc,表示截断(truncate)文件,即清空已有内容,然后重新写入数据。


ios::trunc 作用

当你以 ios::out | ios::trunc 模式打开文件时:

  1. 如果文件已存在它的内容会被清空

  2. 如果文件不存在,则创建一个新文件。

void Management_system::cleanall()
{
    cout << "确认清空?" << endl;
    cout << "1、确认" << endl;
    cout << "2、返回" << endl;
    int sel;
    cin>>sel;
    if(sel==1)
    {
        ofstream ofs;
        ofs.open(FILENAME,ios::trunc);
        ofs.close();
        if(this->arry!=NULL)
        {
            for(int i=0;i<this->max_num;i++)
            {
                    if(this->arry[i]!=NULL)
                    {
                        delete this->arry[i];
                    }
            }
            delete[] this->arry;
            this->max_num=0;
            this->arry=NULL;
            this->isempty=1;
        }
        cout << "清空成功!" << endl;
    }
    system("pause");
    system("cls");
}

析构函数和展示菜单

//析构函数
Management_system::~Management_system()
{
    if (this->arry != NULL)
    {
        for (int i = 0; i < this->max_num; i++) {
            delete this->arry[i];  // 释放每个 worker 对象
        }
        delete[] this->arry;  // 释放指针数组
    }

}




//展示菜单
void Management_system::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;
}

问题1,woker定义好之后,在员工,经理,老板的类里又重定义了各种信息,导致数据存储的时候发生错误
问题2,没有ofs.close()