Я новичок в C ++, хотя у меня небольшой опыт работы с Java.Попытка подойти к следующей проблеме (это часть большой задачи моего университета)
class myCustomer :public Customer {/.../}
class myFlight:public Flight {/.../}
class myEmployee :public Employee {/.../}
class myPlane :public Plane {/.../}
Таким образом, Customer - это интерфейс, а myCustomer - производный класс с реализацией, то же самое относится и к остальным.(Я должен использовать это таким образом)
После этого (своего рода) API для базы данных летной компании;
class MyImplementation{
//I want to link id's to an object so i can call object pointer using a given id
map <string,myCustomer*> customers_map;
map <string,myEmployee*> employees_map;
map <string,myReservation*> reservations_map;
map <string,myPlane*> planes_map;
map <string,myFlight*> flights_map;
...
//must implement this function
virtual Customer* addCustomer(string full_name, int priority){
if(!customers_loaded){
load_customers();
}
auto curr_customer = new myCustomer(id,full_name,priority);
customers_map.insert(pair<string,myCustomer*>(id,curr_customer));
}
void load_customers(){
vector<string> parameters;
string line;
fstream customers_file;
customers_file.open(CUSTOMER_INFO_PATH,fstream::out);
//check if null is returned
if (!customers_file.is_open()) {
throw "Error:cannot open employees file";
}
//iterate over lines
while(getline(customers_file,line)){
//just a function to split a line from file to a vector
parameters=splitLine(line,SPLITTER);
try{
customer_from_string(parameters);
}catch(...){
//could not load current object
cout << "Could not load customer "<< parameters[0] <<
"(line number:"<< lineNumber << ")" <<endl;
continue;
}
}
customers_file.close();
}
void customer_from_string(vector<string> parameters){
string id = parameters[0];
string name = parameters[1];
int priority = stoi(parameters [2];
auto curr_customer = new myCustomer(id,name,priority);
customers_map.insert(pair<string,myCustomer*>(id,curr_customer));
}
void employee_from_string(vector<string>& parameters,
map<string, string>& toLink) {
//get parameters
string employee_id = parameters[0];
Jobs job = string_to_job(parameters[1]);
int seniority = stoi(parameters[2]);
int year = stoi(parameters[3]);
string employer_id = parameters[4];
//check if employee_id is legal
if (employer_id.empty()) {
throw "Employer ID cannot be an empty argument";
}
auto curr_employee = new myEmployee(employee_id, job, seniority,year);
//add to employee map
employees_map.insert(pair<string, myEmployee *>(employee_id, curr_employee));
}
/** more code**/
Поэтому я пытаюсь прочитать параметры из текстового файла и создать указанные объекты, используя соответствующие функции, такие как customer_from_string, employee_from_string, и я должен сделать это для других классов (Самолеты, Бронирование, Полеты ...) у каждого есть свой конструктор с разным количеством параметров.Единственная связь между этими классами состоит в том, что все они реализуют интерфейс ID, который имеет функцию:
virtual string getID() = 0;
Попытка избежать следующего дублирования кода (поэтому я не буду создавать функцию загрузки для каждого объекта):
void load_employees() {
/** same code as load_customers**/
//iterate over lines
while (getline(employees_file, line)) {
//as before
parameters = splitLine(line, SPLITTER);
try {
/*the only change - it has different implementation than customer_from_string*/
employee_from_string(parameters);
} catch (...) {
/** print error **/
}
}
/** as before **/
}
Я понимаю, что мне нужно подойти к этому, используя шаблон проектирования фабрики (поскольку мне нужно динамически создавать объекты, перечисленные в текстовом файле, загружая их в базу данных каждый раз, когда я открываю программу), поэтому я подумало реализации следующего:
class Factory {
virtual void create(vector<string>& parameters,
map<string,Factory*>&id_map,/*..more parameters*/)=0;
}
и пусть метод загрузки решит, какой объект создать (возможно, отправит символ в качестве идентификатора), используя метод create, описанный выше, пусть каждый класс реализует интерфейс фабрики, а затем - с помощьюсоздать функцию, как показано ниже:
//Implementation for customer
void create(vector<string>& parameters,map<Factory *, string>&
toLink,map<string,Factory*>& id_map){
string id = parameters[0];
string name = parameters[1];
int priority = stoi(parameters [parameters.size()-1]);
auto curr_customer = new myCustomer(id,name,priority);
id_map.insert(pair<string,Factory *>(id,curr_customer));
}
Так что я думаю, что мне нужно изменить карты на
map <string,Factory *> objectName_map;
Теперь я вроде застрял, так как карта содержит указатель на объект фабрики,и я хочу использовать идентификаторы карт, чтобы сделать следующее:
virtual Customer* getCustomer(string id){ //must implement this function
if(!customers_loaded){
load('Customers');
}
return customers_map.find(id)->second;
}
И я не могу вызывать какие-либо внутренние функции для каждого объектат. д. после, скажем:
void setEmployer(Employee* employer){//...//}
, так как карты содержат Фабрику *.Я пытался сохранить карты такими, какие они есть, но не смог использовать их в функции создания, поскольку он не может конвертировать объект myCustomer * в Factory *.Я немного потерян, пытался найти решения в Интернете, но не повезло, хотя я чувствую, что реализую это неправильно.Заранее спасибо за любую помощь с этим!
* Отредактированный пост, чтобы прояснить проблему