Witam.Chciałem sobie napisać prosty interfejs wejścia-wyjścia do obsługi plików binarnych. Bazowo/abstrakcyjnie typ danych reprezentuje klasa Data. Klasy pochodne klasy Data : TableData oraz ListData są odpowiednio typami reprezentującymi dane dla tabeli oraz rozwijanej listy. Chciałem przeciążyć operatory dla << oraz >> dla ostream i istream. Chciałem żeby kontener główny klasy DataManager( std::list<Data*>) przechowywał obiekty klas pochodnych klasy Data. Wszystko wychodziło dopóki nie użyłem operatora >> dla tych podklas,wystąpiły błędy kompilacji. Poniżej podaję plik data.h zawierający klasę bazową Data oraz jej dwie klasy pochodne.
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <list>
enum class DataState {Good,Bad}; // stan danych
class Data{
friend class DataManager; // klasa do obsługi danych
public:
Data();
private:
DataState state = DataState::Bad;
private:
virtual std::ostream& operator<< (std::ostream&) = 0;
virtual Data& operator>> (std::istream&) = 0;
};
class TableData : public Data{
friend class DataManager; // klasa do obsługi danych
public:
TableData(int,int);
private:
int rowCount = 0;
int columnCount = 0;
std::vector<std::vector<std::string>> data = std::vector<std::vector<std::string>> {};
private:
std::ostream& operator<< (std::ostream&) override;
Data& operator>> (std::istream&) override;
};
class ListData : public Data{
friend class DataManager; // klasa do obsługi danych
public:
ListData();
private:
std::list<std::string> dataList = std::list<std::string>{};
private:
std::ostream& operator<< (std::ostream&) override;
Data& operator>> (std::istream&) override;
};
plik data.cpp
#include "data.h"
Data::Data(){
}
TableData::TableData(int n_rowCount,int n_columnCount) : rowCount{n_rowCount}, columnCount{n_columnCount}{
}
std::ostream& TableData::operator<< (std::ostream& out){
out << "###1" << '\0';
out << this->rowCount << '\0' ;
out << this->columnCount << '\0';
for(int i = 0; i< rowCount;++i)
for(int j = 0; j< columnCount;++j)
out << this->data[i][j] << '\0';
return out;
}
Data& TableData::operator>> (std::istream& in){
in >> this->rowCount;
in >> this->columnCount;
for(int i = 0; i< rowCount;++i)
for(int j = 0; j< columnCount;++j)
in >> this->data[i][j];
return *this;
}
ListData::ListData(){
}
std::ostream& ListData::operator<< (std::ostream& out) {
out << "###2" << '\0';
out << this->dataList.size() << '\0';
for(auto& element : this->dataList)
out << element << '\0';
return out;
}
Data& ListData::operator>> (std::istream& in){
ListData newListData {};
int size{};
in >> size;
std::string buffer{};
for(int i = 0;i< size ; ++i){
in >> buffer;
newListData.dataList.push_back(std::move(buffer));
}
return *this;
}
Definicja klasy DataManager. Obiekty tej klasy przechowują (próbują) przechować wszystkie obiekty klas pochodnych klasy Data
#include "data.h"
class DataManager{
public:
DataManager();
~DataManager();
void getDataStreamFromFile();
void loadDataStreamToFile(const std::list<Data*>&);
void setNewFileDir(const std::string&);
private:
std::fstream file = std::fstream{};
std::string fileName = std::string{};
std::list<Data*> dataStream = std::list<Data*>{}; // główny kontener
std::list<Data*>::iterator streamIterator = std::list<Data*>::iterator{}; // //pomocniczy iterator
};
Funkcja DataManager::getDataStreamFromFile() , w której występuje błąd kompilacji , którego logi podaję pod poniższym kodem.
void DataManager::getDataStreamFromFile(){
if(file.is_open())
file.close();
file.open(fileName,std::ios_base::in | std::ios_base::binary);
if(file.good() && file.is_open()){
std::string key{};
while (!file.eof()) {
file >> key; // dedukcja klasy pochodnej
if (key == "###1"){ // ciąg znaków ,który mówi nam z jakim typem danych(klasą //pochodną) mamy do czynienia
TableData* newTableData = new TableData{0,0};
file >> *newTableData; // <- miejsce wystąpienia błędu kompilacji
dataStream.push_back(newTableData ); // <- tu brak błędu
newTableData->state = DataState::Good;
}
else if(key == "###2"){ // ciąg znaków ,który mówi nam z jakim typem danych(klasą //pochodną) mamy do czynienia
ListData* newListData = new ListData{};
file >> *newListData; // <- miejsce wystąpienia błędu kompilacji
dataStream.push_back(newListData); // <- tu brak błędu
newListData->state = DataState::Good;
}
else{
//zgłoszenie błędu formatu...
}
}
}
}
Logi:
23:9 error: no match for 'operator>>' (operand types are 'std::fstream {aka std::basic_fstream<char>}' and 'TableData') file >> *newTableData;
23:12: note: cannot convert '* newTableData' (type 'TableData') to type 'signed char*'file >> *newTableData;
Takie same błędy dla drugiej podklasy.
Z góry dziękuję za pomoc :D!