(в основном наклеены из доступ к переменной из другого шаблона класса разделить две проблемы)
я пытаюсь создать систему контейнерных классов, которые можно использовать с классом загрузчика данных для загрузки данных из текстовых файлов
Вот два класса данных:
class Customer
{
//...
};
class Tour
{
std::vector<Customer*> custPtrs;
//...
};
это мои два контейнерных класса:
template <class T>
class P_VContainer
{
boost::ptr_vector<T> data;
//...
};
template <class T>
class ListContainer
{
std::list<T> data;
//...
};
и наконец мой шаблон загрузчика данных:
template<template<class> class T>
class DataLoader
{
T<Customer> custList;
T<Tour> tourList;
//...
};
я перегрузил оператор >> в Customer и Tour, чтобы им можно было передать ifstream, взять строку из потока, токенизировать и поместить ее в переменные экземпляра объекта.
Контейнерные классы обрабатывают вставку по порядку, а загрузчик данных управляет списками и создает ifstream, чтобы его можно было передать объектам.
это моя проблема:
Сначала я загружаю файл с клиентами и заполняю этот список.
после этого мне нужно загрузить туры, которые имеют идентификаторы клиентов для клиентов, которые их забронировали, и я хочу сохранить этих клиентов в векторе указателей на каждом из объектов тура, чтобы информация о клиентах была легко доступна.
в данный момент я сохраняю customerID в виде списка строк, затем, когда все туры загружены, передавая custList в функцию, которая просматривает custList, сопоставляя ее со списком строк
это означает, что мне нужно поддерживать два списка, один из строк и другие указатели, и, в основном, обрабатывать все данные дважды, учитывая, что наборы данных довольно большие, это означает, что время загрузки намного больше.
так что мне было интересно, есть ли способ, которым я могу получить доступ к переменной экземпляра custList из перегруженного >> оператора >> для Tour и генерировать список указателей при создании объектов Tour?
технически все происходит внутри области класса DataLoader, поэтому я думаю, что это должно быть возможно, но я просто не слишком уверен, как это сделать .. может быть, сделать это классом друга? Я пытался сделать это, но пока не повезло ..
любая помощь будет принята с благодарностью, и извините за длинное объяснение, надеюсь, это имело смысл ..
Окончательное использование потока может выглядеть следующим образом:
custStream >> customers >> toursStream >> tours;
Чтобы достичь этого, вы должны обернуть ifstream двумя потоками — для клиентов и для туров и сохранить список клиентов в потоке, вот код, вы можете заменить контейнер на ваш любимый:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
class CustomersInFileStream {
public:
std::vector<Customer> customers;
std::ifstream &input;
CustomersInFileStream(std::ifstream &fileIn)
:input(fileIn){
}
};
class ToursInFileStream {
public:
std::vector<Customer> customers;
std::ifstream &input;
ToursInFileStream(std::ifstream &fileIn)
:input(fileIn){
}
};
CustomersInFileStream &operator>>(CustomersInFileStream &input, std::vector<Customer> customers) {
// perform file parsing here using ifstream member
input.customers = customers;
return input;
}
ToursInFileStream &operator>>(CustomersInFileStream &customersStream,
ToursInFileStream &toursStream) {
toursStream.customers = customersStream.customers;
return toursStream;
}
ToursInFileStream &operator>>(ToursInFileStream &input, std::vector<Tour> tours) {
// perform file parsing here using ifstream member
// you also do have customers list here
return input;
}
int main()
{
std::ifstream customersFile("~/customers.txt");
std::ifstream toursFile("~/tours.txt");
CustomersInFileStream custStream(customersFile);
ToursInFileStream toursStream(toursFile);
std::vector<Customer> customers;
std::vector<Tour> tours;
custStream >> customers >> toursStream >> tours;
return 0;
}
Других решений пока нет …