Довго я пробував доробити функції для запису і читання будь-яких структур в двійковому файлі, але все одно не виходить. Тому я написав у структурі base(про яку я писав у попередньому повідомлені) метод "ручного запису". (дивіться нижче writeBase, readBase)
Що до POD структур я доробив функції, і тепер вони з ними працюють.
Записати структуру даних (мається на увазі не struct, а будь-яку структуру (int, class, union, etc...))
template<typename T>
void writeStructure(T obj, string pathToFile) try
{
if (!std::is_pod<T>::value)
{
throw exception("Cannot write non-POD data");
}
ofstream *outFile = new ofstream;
outFile->open(pathToFile, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
if(outFile->is_open())
{
outFile->write( reinterpret_cast<char*>(&obj), sizeof(obj) );
}
else
{
throw exception("Cannot open file");
}
outFile->close();
delete outFile;
}
catch (exception &e)
{
cerr << "Error! " << e.what();
getchar();
exit(EXIT_FAILURE);
}
Прочитати структуру даних
template<typename T>
T *readStructure(string pathToFile) try
{
if (!std::is_pod<T>::value)
{
throw exception("Cannot read non-POD data");
}
T *obj = nullptr;
ifstream *inFile = new ifstream;
inFile->open(pathToFile, std::ifstream::in | std::ifstream::binary);
if (inFile->is_open())
{
obj = new T;
inFile->read( reinterpret_cast<char*>(obj), sizeof(*obj) );
}
else
{
throw exception("Cannot open file");
}
inFile->close();
delete inFile;
return obj;
}
catch (exception &e)
{
cerr << "Error! " << e.what();
getchar();
exit(EXIT_FAILURE);
}
Наприклад:
Структура
struct MyStruct
{
int a;
char b;
double c;
long long d;
};
Запис і читання
/*Просто перевірка*/
cout << std::is_pod<MyStruct>::value << '\n';//true
cout << sizeof(MyStruct) << '\n';//20
cout << sizeof(MyStruct::a) + sizeof(MyStruct::c) + sizeof(MyStruct::d) << '\n';//24
MyStruct *obj3 = new MyStruct;
obj3->a = 7;
obj3->b = 'q';
obj3->c = 6.9547;
obj3->d = 123456789;
cout << "Show object\n";
writeStructure(*obj3, "file");//НЕ "obj3" а "*obj3" - якщо передати посилання то й запишеться посилання
MyStruct *obj4(readStructure<MyStruct>("file"));
cout << obj4->a << endl;//7
cout << obj4->b << endl;//'q'
cout << obj4->c << endl;//6.9547
cout << obj4->d << endl;//123456789
delete obj4;
Я довго шукав інформацію про купу, але безрезультатно, це ж не воно (make_heap) ? Тому я не знаю як отримати до неї доступ.
Щодо глибокого копіювання, щоб їм скористатися потрібно знати назви всіх полів структури ? Бо я не знаю як інакше їм можна скористатися, я його застосував в структурі base написавши методи writeBase, readBase
Отут
outFile->write(reinterpret_cast<char*>(&name[0]), sizeName);//записую n комірок пам'яті (де n - sizeName)
struct base
{
string name;
time_t currentDate;
void writeBase()
{
ofstream *outFile = new ofstream;
outFile->open("file", std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
if (outFile->is_open())
{
size_t sizeName = name.size();
outFile->write(reinterpret_cast<char*>(&sizeName), sizeof(sizeName));
outFile->write(reinterpret_cast<char*>(&name[0]), sizeName);
outFile->write(reinterpret_cast<char*>(¤tDate), sizeof(currentDate));
}
outFile->close();
delete outFile;
}
void readBase()
{
ifstream *inFile = new ifstream;
inFile->open("file", std::ifstream::in | std::ifstream::binary);
if (inFile->is_open())
{
size_t sizeName;
inFile->read(reinterpret_cast<char*>(&sizeName), sizeof(sizeName));
name.resize(sizeName);
inFile->read(reinterpret_cast<char*>(&name[0]), sizeName);
inFile->read(reinterpret_cast<char*>(¤tDate), sizeof(currentDate));
}
inFile->close();
delete inFile;
}
};
Наприклад:
base *obj1 = new base;
obj1->name = "Axel";
time(&obj1->currentDate);
obj1->writeBase();
base *obj = new base();
obj->readBase();
cout << obj->name << endl;
cout << ctime(&obj->currentDate) << endl;
delete obj;
Але як мені застосувати глибоке копіювання в шаблонних функція writeStructure/readStructure ?