Więc tak Bracie - ja użyłbym szablonu aby dać sobie radę z dowolnym typem danych, tak jak to robi na przykład std::vector. Tak mniej więcej by ona wyglądała:
enum DataLoaderErrors
{
isOK = 0,
emptyDataFileName,
fileNotFound,
fileOpeningError,
fileIsEmpty
};
template<typename T>
class DataLoader
{
public:
explicit DataLoader(const std::string &pathAndFileName);
explicit DataLoader() = default;
virtual ~DataLoader() = default;
virtual DataLoaderErrors loadDataFromFile();
virtual void setDataFile(const std::string &pathAndFileName);
virtual const std::string& getDataFile() const;
virtual const std::vector<T>& getDataConst() const;
virtual std::vector<T>& getData();
protected:
std::vector<T> data;
std::string dataFile;
};
Co do typu T trzeba by dodatkowo dać mu wymóg, że będzie umiał zrobić formatowanie ifstream >> T;
przeciążając operator. Ale to bez obaw, jak ktoś zapomni to już przy kompilacji mu się to posypie.
Dzięki takiemu podejściu będziesz miał Bracie sympatyczną klasę która sobie poradzi z każdym typem danej spełniającej powyższy warunek. Co więcej, ponieważ ten DataLoader jest klasą to ktoś będzie mógł go odziedziczyć, i dopisać potrzebne mu nowe zdolności, ot np, DataHandlera który nie tylko będzie potrafił czytać z pliku dane typu T i zapisywać je do wektora, ale także zapisywać je z wektora do pliku, a najlepsze w tym jest to, że nie będzie musiał zawracać ci przy tym d**y o dopisanie czegoś.