Qt. Как сериализовать объекты содержащие коллекции? В общем имеются вот такие вот классы:class Institution //Класс "учебное заведение"
{
...
private:
...
QList Pupils; //Коллекция учеников
};
class Pupil //Класс "ученик"
{
...
private:
...
QList Lessons; //Коллекция предметов
};
class Exam //Класс "экзамен"
{
...
};
Необходимо сериализовать коллекцию объектов класса Institution (хотя я не уверена уместно ли называть это сериализацией), а именно сохранить это коллекцию в бинарник и потом "взять" её от туда.
Сохранение (здесь проблем нет, т. е. sizeof работает как надо):QList institutions;
...
Institution bf("", 0);
char str[1024];
strcpy(str, filename.toStdString().c_str());
std::ofstream out(str, std::ios::out | std::ios::binary);
for (int i = 0; i < institutions.size(); i++)
{
bf = *institutions[i];
int a = sizeof bf;
out.write((char *) &bf, sizeof bf);
}
out.close();
Считывание (здесь, понятное дело, sizeof не работает, т. к. размер вложенных коллекций заранее не определить):QList institutions;
...
institutions.clear();
char str[1024];
strcpy(str, filename.toStdString().c_str());
std::ifstream in(str, std::ios::in | std::ios::binary);
while (!in.eof() && in.peek() != EOF)
{
Institution *bf = new Institution("", 0);
int a = sizeof bf;
in.read((char *) bf, sizeof *bf); //!
institutions.append(bf);
}
in.close();
Теперь и вопрос, как всё-таки можно записать и считать эту коллекцию в/из бинарника, не изменяя структуру классов(!)?
Или может быть есть что-то подобное как в Java?/*Коллекция*/
ArrayList list = new ArrayList();
/*Запись*/
try
{
FileOutputStream fos = new FileOutputStream(file.toString());
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(list);
oos.close();
fos.close();
}
catch(IOException ioe)
{
}
/*Считывание*/
FileInputStream fis = new FileInputStream(file.toString());
ObjectInputStream ois = new ObjectInputStream(fis);
try
{
list = (ArrayList) ois.readObject();
}
catch (ClassNotFoundException e)
{
}
ois.close();
fis.close();

21 Авг 2019 в 07:05
273 +1
0
Ответы
1

Для сериализации объектов содержащих коллекции в Qt, можно воспользоваться классом QDataStream.
Например, для сохранения коллекции учебных заведений в бинарный файл можно воспользоваться следующим кодом:

QList<Institution *> institutions;
// добавление учебных заведений в коллекцию
QFile file("filename.bin");
if (file.open(QIODevice::WriteOnly)) {
QDataStream out(&file);
out << institutions.size();
for (int i = 0; i < institutions.size(); i++) {
out << *institutions[i];
}
file.close();
}

И для чтения коллекции из бинарного файла:

QList<Institution *> institutions;
QFile file("filename.bin");
if (file.open(QIODevice::ReadOnly)) {
QDataStream in(&file);
int size;
in >> size;
for (int i = 0; i < size; i++) {
Institution *institution = new Institution("", 0);
in >> *institution;
institutions.append(institution);
}
file.close();
}

Для того чтобы объекты классов Institution, Pupil и Exam могли быть сериализуемыми с помощью QDataStream, необходимо определить операторы << (для записи) и >> (для чтения) для каждого класса. Например:

QDataStream &operator<<(QDataStream &out, const Institution &institution)
{
out << institution.Pupils.size();
for (int i = 0; i < institution.Pupils.size(); i++) {
out << *institution.Pupils[i];
}
return out;
}
QDataStream &operator>>(QDataStream &in, Institution &institution)
{
int size;
in >> size;
for (int i = 0; i < size; i++) {
Pupil *pupil = new Pupil();
in >> *pupil;
institution.Pupils.append(pupil);
}
return in;
}
// Аналогично для классов Pupil и Exam

Таким образом, вы можете сохранить и загрузить коллекцию объектов содержащих коллекции из бинарного файла, не изменяя структуру классов.

20 Апр 2024 в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир