Russian Qt Forum
Май 08, 2024, 11:13 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: сериализация объекта пользовательского класса  (Прочитано 4662 раз)
SubaroMows
Гость
« : Ноябрь 02, 2011, 08:04 »

У меня есть класс MyClass.
Я создаю объект
MyClass *obj = new MyClass(this);

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

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

Какие инструменты в Qt для этого существуют?
Записан
SASA
Гость
« Ответ #1 : Ноябрь 02, 2011, 10:25 »

MyClass должен поддерживать сериализацию.
Например сохранять данные в поток, и восстанавливать данные из потока.
Записан
SubaroMows
Гость
« Ответ #2 : Ноябрь 02, 2011, 15:37 »

Да мне кажется это больно сложно, должны быть более простые способы.
Записан
Янковский Александр
Гость
« Ответ #3 : Ноябрь 02, 2011, 15:48 »

Чем boost не нравится?
Очень просто реализуется и великолепно сериализует объекты пользовательских классов в архивы с последующей их загрузкой...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Ноябрь 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");
}
 
« Последнее редактирование: Ноябрь 02, 2011, 18:59 от Igors » Записан
Странник
Гость
« Ответ #5 : Ноябрь 02, 2011, 20:15 »

это если сериализуемый объект не содержит данных-указателей.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Ноябрь 02, 2011, 20:52 »

это если сериализуемый объект не содержит данных-указателей.
А что же меняется если содержит? Улыбающийся Все чудесные системы (в том числе и песня с registerMetaType) сводятся к одному - какой-то идентификатор (ID. строку - дело вкуса) в поток I/O надо записать чтобы потом тип объекта распознать. Можно конечно не писать полагая что типы объектов и порядок их следования никогда не изменится  - но это совсем плохо. 
Записан
Странник
Гость
« Ответ #7 : Ноябрь 02, 2011, 22:20 »

А что же меняется если содержит? Улыбающийся
для не-POD в принципе некошерно оперировать с представлением объекта в памяти. или я опять проспал мировую революцию?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #8 : Ноябрь 02, 2011, 22:34 »

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

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Ноябрь 02, 2011, 23:25 »

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

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

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

Записан
Странник
Гость
« Ответ #10 : Ноябрь 03, 2011, 00:00 »

в качестве простейшего примера такое решение в лоб подходит, конечно. вот только в реальной жизни обычно все сложнее, и простейшие примеры не помогают = ) в любом случае, от предположений о представлении объекта в памяти я бы воздержался и пилил бы руками, сохраняя\загружая значения отдельных свойств.
Записан
SubaroMows
Гость
« Ответ #11 : Ноябрь 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();
« Последнее редактирование: Ноябрь 03, 2011, 08:22 от SubaroMows » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Ноябрь 03, 2011, 10:36 »

Чего же записываем с ReadOnly. а читаем с WriteOnly? Надо наоборот, и операторы >> << тоже попутаны. То что Вы привели - просто запись/чтение объекта в файл - это не имеет никакого отношения к сериализации. Но в любом случае для MyClass нужно самому определять операторы   >> <<
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.073 секунд. Запросов: 22.