Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 保存对象';将类类型转换为文件,并在C++;_C++_File Io_Save_Object Type - Fatal编程技术网

C++ 保存对象';将类类型转换为文件,并在C++;

C++ 保存对象';将类类型转换为文件,并在C++;,c++,file-io,save,object-type,C++,File Io,Save,Object Type,我的程序是,我有一个抽象的Employee类,它有3个继承子类:Manager、Research和Engineer 所有3个都有3个公共数据,然后存储它们自己的数据 这3个类必须通过指向Employee类的指针向量存储,然后向下转换每个元素 最后,它还具有保存到文件和从文件加载的功能 我可以做任何事情,除了加载数据回来。问题是,在代码的开头,我如何定义向量的每个元素都是一个特定的继承类;e、 g:vec[0]是经理,vex[1]是工程师,依此类推 这是我所有的代码。我试过的问题代码在void M

我的程序是,我有一个抽象的Employee类,它有3个继承子类:Manager、Research和Engineer

所有3个都有3个公共数据,然后存储它们自己的数据

这3个类必须通过指向Employee类的指针向量存储,然后向下转换每个元素

最后,它还具有保存到文件和从文件加载的功能

我可以做任何事情,除了加载数据回来。问题是,在代码的开头,我如何定义向量的每个元素都是一个特定的继承类;e、 g:vec[0]是经理,vex[1]是工程师,依此类推

这是我所有的代码。我试过的问题代码在void MenuControl()开关案例5中

#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include<iostream>
#include <string>
#include <fstream>

using namespace std;

class Employee
{
    public:
        Employee();
        virtual void BasicInfo()=0;
        virtual void DisplayInfo()=0;
        virtual void SaveInfo(ofstream& outFile)=0;
        virtual void LoadInfo(ifstream& inFile)=0;
        ~Employee();
    protected:
        string f_Name, l_Name;
        int salary;
};


Employee::Employee(){}
Employee::~Employee(){}

void Employee::BasicInfo()
{

}

void Employee::DisplayInfo()
{

}
#endif
\ifndef员工
#定义雇员
#包括
#包括
#包括
使用名称空间std;
班级员工
{
公众:
雇员();
虚拟void BasicInfo()=0;
虚拟void DisplayInfo()=0;
虚拟空存储信息(流和流文件的存储信息)=0;
虚拟空隙荷载信息(ifstream&inFile)=0;
~Employee();
受保护的:
字符串f_Name,l_Name;
国际工资;
};
Employee::Employee(){}
雇员::~Employee(){}
void Employee::BasicInfo()
{
}
void Employee::DisplayInfo()
{
}
#恩迪夫
\ifndef经理
#定义经理
#包括
#包括
#包括
#包括“Employee.h”
使用名称空间std;
班级经理:公职人员
{
公众:
经理();
管理器(字符串fName、字符串lName、int sal);
void BasicInfo();
void DisplayInfo();
void SaveInfo(流和流出文件);
无效荷载信息(ifstream和INFLE);
~Manager();
受保护的:
int假期,见面;
};
#恩迪夫
//经理:经理(字符串fName,字符串lName,int sal):雇员(f_名称,l_名称,薪水){}
Manager::Manager(){}
管理器::管理器(字符串fName、字符串lName、int-sal)
{
f_Name=fName;
l_Name=lName;
薪金=sal;
}
void管理器::BasicInfo()
{

cout一种方法是在employee类中定义一个类型变量,然后在每个派生构造函数中分配该变量,然后保存/加载此信息

快速示例代码,以举例说明我的建议:

// inside Employee.h
enum eEmployeeTypes
{
   ET_NONE,
   ET_MANAGER,
   ET_RESEARCHER,
   ET_ENGINEER
}

class Employee
{
  ...
  protected:
  eEmployeeTypes m_Type;
}

//employee cpp
Employee::Employee()
{
  ...
  m_Type = ET_NONE
}

// Sample modified constructor for Manager
// manager.cpp
Manager::ManageR()
{
  ...
  m_Type = ET_MANAGER;
}
现在是棘手的部分,因为您需要加载时的信息:

您应该首先将类型信息保存在文件中

然后,您应该为Employee创建一个Factory函数,该函数使用适当的构造函数,如下所示:

static Employee* CreateEmployeeFromFile(ifstream& file)
{
    eEmployeeTypes type;
    file.read((eEmployeeTypes*)&type, sizeof(eEmployeeTypes));
    Employee* rez=null;
    if (type == ET_MANAGER)
    {
       rez = new Manager();
       rez.LoadInfo(file);
    }
    ...
    return rez;
}

好的,我会测试你的方法。但是,如果我只是在数据中输入一个与每个员工类型相关的int,而不是一个Enum,这也会起作用吗?例如:我将Manager设置为1,将research设置为2,依此类推,然后在加载时从文件中读取,运行一个switch或if循环,就像你正在做的那样,并将每个元素实例化为相同的?Tha无论如何,我会测试它并批准这个答案:Enums和INTS实际上是C++中的相同的东西,它只是帮助您具有连续递增的常量值。编译器可能选择将枚举转换为字节/短,这就是为什么使用枚举使用SIZEONE EnUM更安全,而不是直接假设它是int。。因此,在将其保存在二进制文件中时,我将其大小指定为sizeof(eEmployeeTypes)?如果使用枚举,是的,这就是您想要的:)。您可以做的一个小技巧是强制枚举为int,这样,如果您使用不同的编译器,您以后就不会遇到不匹配的情况。这是指向该技巧的链接(第二个答案是您正在搜索的答案):很抱歉,回复太晚。我尝试了与您的完全相同的方式,但出现了一些错误,所以我只是简单地更正了错误,我很乐意去做!非常感谢您的帮助!:)
#ifndef ENGINEER_H
#define ENGINEER_H


#include <iostream>
#include <string>
#include <fstream>
#include "Employee.h"
using namespace std;

class Engineer : public Employee
{
    public:
        Engineer();
        Engineer(string fName, string lName, int sal);
    //  void BasicInfo(bool knowCPP, int experience, string type);
        void BasicInfo();
        void DisplayInfo();
        void SaveInfo(ofstream& outFile);
        void LoadInfo(ifstream& inFile);
        ~Engineer();
    protected:
        bool isknowingCPP;
        int exp;
        string typeOfEng;
};
#endif
Engineer::Engineer(){}
Engineer::Engineer(string fName, string lName, int sal)
{
    f_Name = fName;
    l_Name = lName;
    salary = sal;
}

void Engineer::BasicInfo()
{
    cout<<endl<<"Knows C++(0/1): ";
    cin>>isknowingCPP;
    cout<<endl<<"Years of Experience: ";
    cin>>exp;
    cout<<endl<<"Field of Engineering: ";
    cin>>typeOfEng;
}

void Engineer::DisplayInfo()
{
    cout<<"TYPE: Engineer";
    cout<<endl<<"Name: "<<f_Name<<" "<<l_Name;
    cout<<endl<<"Salary: "<<salary<<endl;
    cout<<"Knows C++: "<<isknowingCPP;
    cout<<endl<<"Experience: "<<exp;
    cout<<endl<<"Engineering: "<<typeOfEng;
    cout<<endl<<endl;
}

Engineer::~Engineer()
{

}

void Engineer::SaveInfo(ofstream& outFile)
{
    outFile.write((char*)&f_Name, sizeof(string));
    outFile.write((char*)&l_Name, sizeof(string));
    outFile.write((char*)&salary, sizeof(int));
    outFile.write((char*)&isknowingCPP, sizeof(bool));
    outFile.write((char*)&exp, sizeof(int));
    outFile.write((char*)&typeOfEng, sizeof(string));
    /*outFile<<"Engineer";
    outFile<<endl<<"FirstName: "<<f_Name;
    outFile<<endl<<"LastName: "<<l_Name;
    outFile<<endl<<"Salary: "<<salary;
    outFile<<endl<<"Knows C++: "<<isknowingCPP;
    outFile<<endl<<"Experience: "<<exp;
    outFile<<endl<<"Engineering: "<<typeOfEng;
    outFile<<endl<<endl;*/
}

void Engineer::LoadInfo(ifstream& inFile)
{
    inFile.read((char*)&f_Name, sizeof(string));
    inFile.read((char*)&l_Name, sizeof(string));
    inFile.read((char*)&salary, sizeof(int));
    inFile.read((char*)&isknowingCPP, sizeof(bool));
    inFile.read((char*)&exp, sizeof(int));
    inFile.read((char*)&typeOfEng, sizeof(string));
}
#include <iostream>
#include <string>
#include <vector>

#include "Engineer.h"
#include "Manager.h"
#include "Researcher.h"

using namespace std;

void MenuControl(int id);
void AddEmployee(int type);
void DeleteEmployee(int id);
int empStrength;
bool quit = false;
vector<Employee*> emps;
int main()
{
    /*Manager* man = new Manager("Shash", "Sharma", 30);
    emps.push_back(man);
    emps[0]->BasicInfo();*/
    int optionID;
    //delete emps[0];
    while(!quit)
    {
        cout<<endl<<"1) Add Employee \n2) Delete Employee \n3)Display List \n4)Save Data \n5)Load Data \nAny other number to Quit: ";
        cin>>optionID;
        MenuControl(optionID);
    }
}

void MenuControl(int id)
{
    switch(id)
    {
        case 1:
            {
                int empType;
                cout<<endl<<endl<<"Adding Employee..."<<endl;
                cout<<endl<<"Please choose Employee category: "<<endl<<"1)Manager\n2)Researcher\n3)Engineer\nAny other number to exit: ";
                cin>>empType;
                AddEmployee(empType);
                break;
            }

        case 2:
            {
                int deleteID;
                cout<<endl<<"Deleting Employee..."<<endl;
                cout<<endl<<"Enter Employee Code: ";
                cin>>deleteID;
                DeleteEmployee(deleteID);
                break;
            }

        case 3:
            {
                if(emps.size()>0)
                {
                    for(int i=0; i<emps.size(); i++)
                    {
                        emps[i]->DisplayInfo();
                    }
                }
                else
                    cout<<endl<<"No data available!"<<endl;

                break;
            }

        case 4:
            {
                if(emps.size()>0)
                {
                    ofstream outfile("EmployeeData.txt", ios_base::binary);
                    for(int i=0; i<emps.size(); i++)
                    {
                        emps[i]->SaveInfo(outfile);
                    }
                    outfile.close();


                    ofstream outfile02("Employees.dat", ios_base::binary);
                    outfile02.write((char*)&empStrength, sizeof(int));
                    cout<<endl<<"Employee Strength: "<<empStrength;
                    outfile02.close();


                    ofstream outfile03("EmployeeTypes.txt", ios_base::binary);
                    for(int i=0; i<emps.size(); i++)
                    {
                        //outfile03<<&emps[i]<<endl;
                        outfile03.write(reinterpret_cast<char*>(&emps[i]) , sizeof(Employee));
                    }
                }
                cout<<endl<<"Data Saved";
                cout<<endl<<endl;
                break;
            }

        case 5:
            {
                ifstream infile02("Employees.dat", ios_base::binary);
                infile02.read((char*)&empStrength, sizeof(int));
                cout<<endl<<"Employee Strength: "<<empStrength;
                emps.resize(empStrength);
                cout<<endl<<emps.size();

                Employee* temp;
                ifstream infile03("EmployeeTypes.txt", ios_base::binary);
    //          infile03.read(reinterpret_cast<char*>(&temp), sizeof(Employee));
                for(int i=0; i<emps.size(); i++)
                {
                    cout<<endl<<"BeforeSeg";
                    infile03.read(reinterpret_cast<char*>(temp), sizeof(Employee));
                    cout<<endl<<"SegError";
                    emps[i] = temp;
                }
                break;
            }

        default:
            {
                quit = true;
                break;
            }
    }
}

void AddEmployee(int type)
{
    string fName, lName;
    int sal;
    switch(type)
    {
        case 1:
            {
            //, holiday, meetings;
            cout<<endl<<endl<<"First Name: ";
            cin>>fName;
            cout<<endl<<"Last Name: ";
            cin>>lName;
            cout<<endl<<"Salary: ";
            cin>>sal;
            Manager* man = new Manager(fName, lName, sal);
            man->BasicInfo();
            emps.push_back(man);
            empStrength++;
            break;
            }

        case 2:
            {
            cout<<endl<<endl<<"First Name: ";
            cin>>fName;
            cout<<endl<<"Last Name: ";
            cin>>lName;
            cout<<endl<<"Salary: ";
            cin>>sal;
            Researcher* res = new Researcher(fName, lName, sal);
            res->BasicInfo();
            emps.push_back(res);
            empStrength++;
            break;
            }

        case 3:
            {
            cout<<endl<<endl<<"First Name: ";
            cin>>fName;
            cout<<endl<<"Last Name: ";
            cin>>lName;
            cout<<endl<<"Salary: ";
            cin>>sal;
            Engineer* eng = new Engineer(fName, lName, sal);
            eng->BasicInfo();
            emps.push_back(eng);
            empStrength++;
            break;
            }

        default:
            cout<<endl<<endl<<"No such Employee Type. Please put correct values"<<endl;
    }
}

void DeleteEmployee(int id)
{
    if(id<emps.size())
    {
        emps.erase(emps.begin() + id);
        empStrength--;
    }
    else
    {
        cout<<endl<<"No such ID yet."<<endl;
    }
}
// inside Employee.h
enum eEmployeeTypes
{
   ET_NONE,
   ET_MANAGER,
   ET_RESEARCHER,
   ET_ENGINEER
}

class Employee
{
  ...
  protected:
  eEmployeeTypes m_Type;
}

//employee cpp
Employee::Employee()
{
  ...
  m_Type = ET_NONE
}

// Sample modified constructor for Manager
// manager.cpp
Manager::ManageR()
{
  ...
  m_Type = ET_MANAGER;
}
static Employee* CreateEmployeeFromFile(ifstream& file)
{
    eEmployeeTypes type;
    file.read((eEmployeeTypes*)&type, sizeof(eEmployeeTypes));
    Employee* rez=null;
    if (type == ET_MANAGER)
    {
       rez = new Manager();
       rez.LoadInfo(file);
    }
    ...
    return rez;
}