Russian Qt Forum

Qt => Вопросы новичков => Тема начата: SubaroMows от Ноябрь 02, 2011, 08:04



Название: сериализация объекта пользовательского класса
Отправлено: SubaroMows от Ноябрь 02, 2011, 08:04
У меня есть класс MyClass.
Я создаю объект
MyClass *obj = new MyClass(this);

Мне нужно сохранить этот объект и потом загрузить.
Какие способы есть?

Пробовал QDataStream, сохранять получается, а загрузить нет.

Какие инструменты в Qt для этого существуют?


Название: Re: сериализация объекта пользовательского класса
Отправлено: SASA от Ноябрь 02, 2011, 10:25
MyClass должен поддерживать сериализацию.
Например сохранять данные в поток, и восстанавливать данные из потока.


Название: Re: сериализация объекта пользовательского класса
Отправлено: SubaroMows от Ноябрь 02, 2011, 15:37
Да мне кажется это больно сложно, должны быть более простые способы.


Название: Re: сериализация объекта пользовательского класса
Отправлено: Янковский Александр от Ноябрь 02, 2011, 15:48
Чем boost не нравится?
Очень просто реализуется и великолепно сериализует объекты пользовательских классов в архивы с последующей их загрузкой...


Название: Re: сериализация объекта пользовательского класса
Отправлено: Igors от Ноябрь 02, 2011, 18:57
Конечно "везде все есть", но может лучше сначала сделать самому (пусть примитивно) а потом уже (если понадобится)  прильнуть к источнику наслаждения (бусту или др)

Код
C++ (Qt)
enum {
..
IOID_MYCLASS = 100,
..
};
 
// запись
MyClass * test = new MyClass();
...
stream << int (IOID_MYCLASS);
stream << (*test);
 
// чтение (объекты могут следовать в любом порядке)
int type;
stream >> type;
switch (type) {
...
case IOID_MYCLASS:
 {
    MyClass * test = new MyClass();
    stream >> (*test);
   //.. здесь определяем считанный объект куда надо
    break;
  }
 ..
 default:
   ShowError("I/O Error");
}
 


Название: Re: сериализация объекта пользовательского класса
Отправлено: Странник от Ноябрь 02, 2011, 20:15
это если сериализуемый объект не содержит данных-указателей.


Название: Re: сериализация объекта пользовательского класса
Отправлено: Igors от Ноябрь 02, 2011, 20:52
это если сериализуемый объект не содержит данных-указателей.
А что же меняется если содержит? :) Все чудесные системы (в том числе и песня с registerMetaType) сводятся к одному - какой-то идентификатор (ID. строку - дело вкуса) в поток I/O надо записать чтобы потом тип объекта распознать. Можно конечно не писать полагая что типы объектов и порядок их следования никогда не изменится  - но это совсем плохо. 


Название: Re: сериализация объекта пользовательского класса
Отправлено: Странник от Ноябрь 02, 2011, 22:20
А что же меняется если содержит? :)
для не-POD в принципе некошерно оперировать с представлением объекта в памяти. или я опять проспал мировую революцию?


Название: Re: сериализация объекта пользовательского класса
Отправлено: LisandreL от Ноябрь 02, 2011, 22:34
А что же меняется если содержит?
Тут встаёт вопрос, что писать вместо него при сериализации:
1) Просто значение указателя нельзя (при десериализации память выделится по другому и этот указатель будет указывать куда угодно, кроме нужного объекта)
2) Можно сериализовать объект, на который указатель указывает, но тут опять 2 но:
  а) а что если у него тоже есть указатели и в итоге получится цикл из указателей?
  б) а что если это указатель на другой сериализуемый объект и нам важна связь, то есть нужно не создать его копию, а указать именно на тот самый объект
3) Писать некоторый ID объекта (решение случая 2.б)


Название: Re: сериализация объекта пользовательского класса
Отправлено: Igors от Ноябрь 02, 2011, 23:25
для не-POD в принципе некошерно оперировать с представлением объекта в памяти. или я опять проспал мировую революцию?
Само собой, операторы << >>  пишут/читают почленно, ни о какой "загрузке блоками" речь не идет

Тут встаёт вопрос, что писать вместо него при сериализации:
1) Просто значение указателя нельзя (при десериализации память выделится по другому и этот указатель будет указывать куда угодно, кроме нужного объекта)
2) Можно сериализовать объект, на который указатель указывает, но тут опять 2 но:
  а) а что если у него тоже есть указатели и в итоге получится цикл из указателей?
  б) а что если это указатель на другой сериализуемый объект и нам важна связь, то есть нужно не создать его копию, а указать именно на тот самый объект
3) Писать некоторый ID объекта (решение случая 2.б)

Ну сериализовать все-все явный перегиб, но достаточно низком уровне можно и нужно делать предположения о порядке данных, главное не забыть записать версию. С "некоторым" ID вопрос конечно интересный, но он далеко выходит за рамки темы топик-стартера. Я хотел показать что в принципе вещь очень простая, самому ее сделать несложно и окружать себя частоколом из QVariant, QMetaType и.т.п. совсем необязательно.



Название: Re: сериализация объекта пользовательского класса
Отправлено: Странник от Ноябрь 03, 2011, 00:00
в качестве простейшего примера такое решение в лоб подходит, конечно. вот только в реальной жизни обычно все сложнее, и простейшие примеры не помогают = ) в любом случае, от предположений о представлении объекта в памяти я бы воздержался и пилил бы руками, сохраняя\загружая значения отдельных свойств.


Название: Re: сериализация объекта пользовательского класса
Отправлено: SubaroMows от Ноябрь 03, 2011, 08:20
Но при загрузке выдаёт ошибку,нету такого типа....
Код:
//Создаём наш класс, означиваем его атрибут
    MyClass *objTest = new MyClass();
    objTest->nameTest = "test";

    //Записываем наш класс, в файл с нашим форматом
    QFile fileSave("test.tfr");
    fileSave.open(QFile::ReadOnly);

    QDataStream in(&fileSave);
    in << objTest;
    fileSave.close();

    //Пытаемся извлечь наш класс

    QFile fileLoad("test.tfr");
    fileLoad.open(QFile::WriteOnly);

    QDataStream out(&fileLoad);
    MyClass *objTest2;
    out >> objTest2;
    fileLoad.close();


Название: Re: сериализация объекта пользовательского класса
Отправлено: Igors от Ноябрь 03, 2011, 10:36
Чего же записываем с ReadOnly. а читаем с WriteOnly? Надо наоборот, и операторы >> << тоже попутаны. То что Вы привели - просто запись/чтение объекта в файл - это не имеет никакого отношения к сериализации. Но в любом случае для MyClass нужно самому определять операторы   >> <<