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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Сериализация объектов  (Прочитано 23943 раз)
deaks
Гость
« : Июнь 14, 2011, 11:38 »

Здравствуйте,

как сделать данный сабж?

прошу не пинать ногами. лучше посоветовать-подсказать или дать ссылку на внятный пример.
спасибо=)

PS в частности интересует, как запаковать QVector<мой объект>
« Последнее редактирование: Июнь 14, 2011, 11:46 от deaks » Записан
deaks
Гость
« Ответ #1 : Июнь 14, 2011, 11:43 »

можно ли обойтись связкой QDataStream и QByteArray?
Записан
asvil
Гость
« Ответ #2 : Июнь 14, 2011, 11:46 »

да
Записан
deaks
Гость
« Ответ #3 : Июнь 14, 2011, 12:08 »

так будет верно?

На отправляющей стороне
Код
C++ (Qt)
QByteArray ba;
QDataStream ds1(&ba, QIODevice::WriteOnly);
QVector<object> objects1;
ds1 << objects2;
 

На принимающей стороне
Код
C++ (Qt)
QDataStream ds2(ba, QIODevice::ReadOnly);
QVector<object> objects2;
ds2.device()->reset();
ds2 >> objects2;
 
Записан
RedDog
Гость
« Ответ #4 : Июнь 14, 2011, 12:13 »

если свой объект не будет содержать в себе указатели на другие объекты и платформозависимые типы данных, тогда прокатит
хотя вряд ли вектор корректно передатся. лучше использовать простые типы/массивы
Записан
deaks
Гость
« Ответ #5 : Июнь 14, 2011, 12:32 »

скорее всего такой вариант -

Код
C++ (Qt)
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
QVector<object> objects;
int size = objects->size();
ds << size;
for(int  i = 0; i < size; i++)
{
   ds << objects[i]->name;
   ds << objects[i]->angle;
   ds << objects[i]->velocity;
}    
[\code]
 
ну и на принимающей стороне все делать в обратном порядке с учетом считанного размера массива
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июнь 14, 2011, 12:40 »

так будет верно?

На отправляющей стороне
...
Так "будет работать", но это не имеет отношения к сериализации Улыбающийся Разница в том что у Вас точно известно какие типы читаются/пишутся, это фиксировано и не может быть изменено в runtime. Cериализация подразумевает что будут (автоматычно) созданы и прочитаны объекты того типа что записаны (а не Вы их создаете и затем читаете). Насколько мне известно, в Qt это делается через Q_DECLARE_METATYPE и затем QVariant. Хороший пример тоже хотел бы увидеть
Записан
deaks
Гость
« Ответ #7 : Июнь 14, 2011, 13:35 »

Цитировать
Насколько мне известно, в Qt это делается через Q_DECLARE_METATYPE и затем QVariant. Хороший пример тоже хотел бы увидеть

может быть это - http://habrahabr.ru/blogs/qt_software/83374/ ?
« Последнее редактирование: Июнь 14, 2011, 14:10 от deaks » Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


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


Просмотр профиля
« Ответ #8 : Июнь 14, 2011, 13:46 »

Так "будет работать", но это не имеет отношения к сериализации Улыбающийся Разница в том что у Вас точно известно какие типы читаются/пишутся, это фиксировано и не может быть изменено в runtime. Cериализация подразумевает что будут (автоматычно) созданы и прочитаны объекты того типа что записаны
Ну на счёт не имеет отношения к сериализациии - это очень сильно сказанно. У троллей в Serializing Qt Data Types ровно такой же механизм описан. Определить по нему какой же тип был сериализован невозможно.


Насколько мне известно, в Qt это делается через Q_DECLARE_METATYPE и затем QVariant. Хороший пример тоже хотел бы увидеть
Увы, в Q_DECLARE_METATYPE нельзя указать MetaTypeID в итоге если данные будут передаваться не между идентичными исполняемыми файлам может получиться, что на разных сторонах один и тот же тип получит разный MetaTypeID ну а дальше кровь, кишки, распи…
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #9 : Июнь 14, 2011, 15:34 »

так будет верно?

На отправляющей стороне
Код
C++ (Qt)
QByteArray ba;
QDataStream ds1(&ba, QIODevice::WriteOnly);
QVector<object> objects1;
ds1 << objects2;
 

На принимающей стороне
Код
C++ (Qt)
QDataStream ds2(ba, QIODevice::ReadOnly);
QVector<object> objects2;
ds2.device()->reset();
ds2 >> objects2;
 


так работать не будет! Надо как минимум реализовать функцию
Код:
QDataStream& operator<<(QDataStream& s, const object& v)
Также интересно что у тебя за обьекты, и можешь ли ты их хранить в контейнерах по значению.
 
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #10 : Июнь 14, 2011, 15:35 »

..... Насколько мне известно, в Qt это делается через Q_DECLARE_METATYPE и затем QVariant. Хороший пример тоже хотел бы увидеть


http://cartan.cas.suffolk.edu/oopdocbook/opensource/exportcode.html
Записан
deaks
Гость
« Ответ #11 : Июнь 14, 2011, 16:25 »

Цитировать

так работать не будет! Надо как минимум реализовать функцию
Код:
QDataStream& operator<<(QDataStream& s, const object& v)
Также интересно что у тебя за обьекты, и можешь ли ты их хранить в контейнерах по значению.
 

вместо этого, в классе реализовал метод сериализации (десериализации) возвращающий (принимающий) QByteArray c записанными полями объекта
то есть так:

Код
C++ (Qt)
bool ShmObject::serialize(QByteArray &ba)
{
QDataStream ds(&ba, QIODevice::WriteOnly);
ds << name;
ds << shape;
ds << psi;
return true;
}
 

где name, shape, psi - поля класса. в результате в ba будут лежать требуемые данные.

так верно?
Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #12 : Июнь 14, 2011, 16:45 »

так верно?

Твой код сериализации обьекта с таким:
Код
C++ (Qt)
QDataStream ds1(&ba, QIODevice::WriteOnly);
QVector<object> objects1;
ds1 << objects2;
работать не будет.
Потому что при сериализации вектора вызывается
Код:
operator<<()
для каждого элемента вектора.


P.S. может попробуй описать задачу поподробней (какие обьекты, от чего наследуются, как хранятся).

Mожет boost::serialization? (http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/index.html)
« Последнее редактирование: Июнь 14, 2011, 16:51 от alex312 » Записан
deaks
Гость
« Ответ #13 : Июнь 14, 2011, 16:49 »

Цитировать

Твой код сериализации обьекта с таким:
Код
C++ (Qt)
QDataStream ds1(&ba, QIODevice::WriteOnly);
QVector<object> objects1;
ds1 << objects2;
работать не будет.
Потому что при сериализации вектора вызывается
Код:
operator<<()
для каждого элемента вектора.


я не буду для сериализации вектора использовать <<. я сериализую каждый объект отдельно, а полученный массив добавляю в поток.

в целом-то подход правильный?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Июнь 14, 2011, 16:54 »

может быть это - http://habrahabr.ru/blogs/qt_software/83374/ ?
Хмм... ну не знаю. Автор пишет
Цитировать
Ведь C++ и так предоставляет достаточно гибкие возможности при сериализации в поток.
Это какие же? Мне известен аж один, выглядит так
Код
C++ (Qt)
int ID = stream.ReadInt();
switch (ID) {
  case ID_OBJ1:
  {
    MyObj1 * obj1 = new MyObj1();
    obj1->Read(stream);
    this->SetData1(obj1);
    break;
  }  
  // и еще столько case сколько типов объектов
 ...
}
 
Запихнуть все подлежащее записи в properties - идея понятна, но на мой взгляд, выигрыша особого не видно. Немного отбили на ручном разборе ID - зато теперь надо как-то держать QVariant/property.

Во всем этом есть малозаметная вещь которая, однако, по сложности превышает в десятки раз обсуждаемое. Написать "сериализацию" в первый раз очень легко. Но вот когда формат данных изменился (что-то отжило, новое добавилось) - вот тут наступает звериный кайф. Выясняется, что старые структуры просто так не снести - файлы перестанут читаться. Поэтому первое что мне бросилось в глаза - автор статьи не пишет число properties в поток - ну наверное у него ничего меняться не будет  Улыбающийся

Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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