Моя программа состоит в том, что у меня есть класс Abstract Employee, который имеет 3 наследующих подкласса: Manager, Исследователь и Инженер.
Все 3 имеют 3 общих данных, а затем свои собственные данные для хранения.
Эти 3 класса должны быть сохранены через вектор указателей на класс Employee, а затем понижены каждый элемент.
Наконец, он имеет функцию Сохранить в и Загрузить из файла.
Я могу сделать все остальное, кроме загрузки данных обратно. Проблема в том, что в начале кода, как мне определить, что каждый элемент вектора имеет определенный унаследованный класс; например: vec [0] — менеджер, vex [1] — инженер, и так далее.
Вот весь мой код Код проблемы, который я пробовал, находится в void MenuControl () Switch Case 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 MANAGER_H
#define MANAGER_H#include<iostream>
#include <string>
#include <fstream>
#include "Employee.h"using namespace std;
class Manager : public Employee
{
public:
Manager();
Manager(string fName, string lName, int sal);
void BasicInfo();
void DisplayInfo();
void SaveInfo(ofstream& outFile);
void LoadInfo(ifstream& inFile);
~Manager();
protected:
int vacation, meets;
};
#endif//Manager::Manager(string fName, string lName, int sal) : Employee(f_Name, l_Name, salary){}
Manager::Manager(){}
Manager::Manager(string fName, string lName, int sal)
{
f_Name = fName;
l_Name = lName;
salary = sal;
}
void Manager::BasicInfo()
{
cout<<endl<<"Enter Number of Vacations: ";
cin>>vacation;
cout<<endl<<"Enter Number of Meetings: ";
cin>>meets;
}
void Manager::DisplayInfo()
{
cout<<endl<<endl<<"TYPE: Manager";
cout<<endl<<"Name: "<<f_Name<<" "<<l_Name;
cout<<endl<<"Salary: "<<salary<<endl;
cout<<"Number of Vacations: "<<vacation;
cout<<endl<<"Meetings per Week: "<<meets;
cout<<endl<<endl<<endl;
}
Manager::~Manager()
{
}
void Manager::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*)&vacation, sizeof(int));
outFile.write((char*)&meets, sizeof(int));
}
void Manager::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*)&vacation, sizeof(int));
inFile.read((char*)&meets, sizeof(int));
}
#ifndef RESEARCHER_H
#define RESEARCHER_H#include <iostream>
#include <string>
#include <fstream>
#include "Employee.h"using namespace std;
class Researcher : public Employee
{
public:
Researcher();
Researcher(string fName, string lName, int sal);
void BasicInfo();
void DisplayInfo();
void SaveInfo(ofstream& outFile);
void LoadInfo(ifstream& inFile);
~Researcher();
protected:
string TopicPhd, SchoolPhd;
};
#endif
Researcher::Researcher(){}
Researcher::Researcher(string fName, string lName, int sal)
{
f_Name = fName;
l_Name = lName;
salary = sal;
}
void Researcher::BasicInfo()
{
cout<<endl<<"Topic of PhD: ";
cin>>TopicPhd;
cout<<endl<<"School of PhD: ";
cin>>SchoolPhd;
}
void Researcher::DisplayInfo()
{
cout<<"RESEARCHER";
cout<<endl<<"Name: "<<f_Name<<" "<<l_Name;
cout<<endl<<"Salary: "<<salary<<endl;
cout<<"PhD: "<<TopicPhd<<"\nSchool: "<<SchoolPhd;
cout<<endl<<endl;
}
void Researcher::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*)&TopicPhd, sizeof(string));
outFile.write((char*)&SchoolPhd, sizeof(string));
}
void Researcher::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*)&TopicPhd, sizeof(string));
inFile.read((char*)&SchoolPhd, sizeof(string));
}
#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;
}
}
Я довольно новичок в C ++, поэтому, пожалуйста, имейте 🙂
Один из подходов состоит в том, чтобы определить переменную типа внутри вашего класса сотрудников, затем назначить эту переменную внутри каждого производного конструктора, а затем сохранить / загрузить эту информацию.
Быстрый пример кода, чтобы проиллюстрировать то, что я предлагаю:
// 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;
}
Теперь начинается сложная часть, так как вам нужна информация во время загрузки:
Вы должны сначала сохранить информацию о типе внутри файла.
Затем вы должны создать функцию Factory для Employee, которая использует конструктор approrpriate и читать что-то вроде:
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;
}