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

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

Страниц: 1 [2] 3 4 ... 8   Вниз
  Печать  
Автор Тема: Сериализация (как сделать поудобнее)  (Прочитано 48105 раз)
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #15 : Февраль 06, 2013, 21:11 »

От увлекающихся обобщенным программированием я ожидал чего-то типа такого
Боюсь вызвать бурю негодования по поводу буста, но! Улыбающийся
Сейчас я не предлагаю использовать его сериализацию, просто предлагаю посмотреть как синтаксически это реализовано у них. Лаконичней и без лишних флагов.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #16 : Февраль 06, 2013, 21:18 »

Код:
TestRecord::TestRecord(){
    push(boolField,"boolField");
    push(charField,"charField");
    push(shortField,"shortField");
    push(intField,"intField");
    push(longField,"longField");
    push(bigintField,"bigintField");
    push(floatField,"floatField");
    push(doubleField,"doubleField");
    push(stringField,"stringField");
    push(dateField,"dateField",BoaDateTime::DateTime);
 }
Здесь каждое поле идентифицируется строкой - дороговато выходит. Также неясно - ну а что дальше что, после того как хапихнули в контейнер (мапу?)

В любом случае в этой функции у вас будет сформированы две функции. Вы их просто сливаете с помощью указания флага. Собственно и предложенная мной функция делает аналогичные действия.
Пример
Код:
void MyStruct::ReadWrite( QDataStream & strm, bool modeWrite )
{
if (modeWrite)
    strm >>  intPoleMyStruct;
    strm >> qstringPoleMyStruct ;
    // здесь еще 100 полей
else
    strm <<  intPoleMyStruct;
    strm << qstringPoleMyStruct ;
    // здесь еще 100 полей
 ...
}
Итого 200 строк. Др вариант
Код
C++ (Qt)
void MyStruct::ReadWrite( QDataStream & strm, int mode )
{
   ReadWrite(strm, &intPoleMyStruct, mode);
   ReadWrite(strm, &qstringPoleMyStruct, mode);
   // здесь еще 100 полей
}
 
Итого 100 строк  Улыбающийся
Записан
Bepec
Гость
« Ответ #17 : Февраль 06, 2013, 21:20 »

Да, Igors это гуд, а шаблоны это сила Улыбающийся

Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #18 : Февраль 06, 2013, 21:26 »

to sergek:

Ваш способ и есть тот камень преткновения. При изменении структуры, придётся переписывать функции send и receive.

Или я не уловил вашу систему и у вас сериализуются типы по их текстовому названию и вызывается соответствующий сериализатор?
Не уловили Подмигивающий При изменении структуры переписывается только конструктор, в котором все сериализуемые поля "сохраняются" методом push. Имена не обязательны, они могут использоваться для доступа к полям путем разыменования (полезно при работе с таблицами БД). А так можно написать:
Код:
    push(boolField);
    push(charField);
    push(shortField);
...
И доступ к полям - обычным образом, и на клиенте и на сервере:
Код:
TestRecord rec;
char ch = rec.charField;
rec.shortField = 123;
Т.е. это обычные классы, только порождены от BoaInterface, в котором все и скрыто (и сериализация, и десериализация, и шифрование и много чего..). Кстати, на основе шаблонов, так не любимых вами Подмигивающий
Главное, чтобы объявления класса и реализация конструктора на клиенте и сервере были одинаковы. Поэтому в моих проектах правило: объявления классов, функций и реализации классов - это общая часть серверной и клиентской части.
Реализации функций - разные.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Февраль 06, 2013, 21:26 »

Боюсь вызвать бурю негодования по поводу буста, но! Улыбающийся
Сейчас я не предлагаю использовать его сериализацию, просто предлагаю посмотреть как синтаксически это реализовано у них. Лаконичней и без лишних флагов.
Та почти так же как я предложил Улыбающийся Но где ж я в Qt возьму Archive который даст мне автоматычно разрулить read/write  Непонимающий
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #20 : Февраль 06, 2013, 21:31 »

Но где ж я в Qt возьму Archive который даст мне автоматычно разрулить read/write  Непонимающий
Дайте подумать. Напишете сами? Улыбающийся
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #21 : Февраль 06, 2013, 21:33 »

Код:
TestRecord::TestRecord(){
    push(boolField,"boolField");
    push(charField,"charField");
    push(shortField,"shortField");
    push(intField,"intField");
    push(longField,"longField");
    push(bigintField,"bigintField");
    push(floatField,"floatField");
    push(doubleField,"doubleField");
    push(stringField,"stringField");
    push(dateField,"dateField",BoaDateTime::DateTime);
 }
Здесь каждое поле идентифицируется строкой - дороговато выходит. Также неясно - ну а что дальше что, после того как хапихнули в контейнер (мапу?)
Да, неудачный пример я привел... Мап тут ни при чем, там шаблоны. И каждая строка (push) передает указатель на член класса, а шаблон уже сам определяет тип и длину данных, передаваемых через сокет. Поэтому накладные расходы - один push на один член, извините, данное класса. Примерно так.
Думаю, альтернатива этому - только препроцессор, а это тема отдельного разговора...
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Февраль 06, 2013, 21:34 »

Дайте подумать. Напишете сами? Улыбающийся
Правда не знаю, я с дустом не очень - так, приобщаюсь к культуре, но не более того  Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #23 : Февраль 06, 2013, 21:39 »

там шаблоны. И каждая строка (push) передает указатель на член класса, а шаблон уже сам определяет тип и длину данных, передаваемых через сокет. Поэтому накладные расходы - один push на один член, извините, данное класса. Примерно так.
То есть как бы "контейнер дескрипторов" который разберется с I/O? Смещение члена+тип (+ может что-то еще). Хммм.. а что делать если данные IO не соответствуют полям напрямую? (так бывает)
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #24 : Февраль 06, 2013, 21:43 »

Правда не знаю, я с дустом не очень - так, приобщаюсь к культуре, но не более того  Улыбающийся
Буст вообще не причем. Нужны два класса (хотя если захотеть, то хватит и одного): oarchive/iarchive, а внутри у них пусть будет QDataStream.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #25 : Февраль 06, 2013, 21:47 »

Давайте так - поставьте конкретную задачу, типа hello, wold (можно сложнее). А я сделаю проект под qt для клиент/серверного приложения. Там и оцените затраты и размер писанного кода. Только не сегодня (результат), а то завтра вставать рано...
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Февраль 06, 2013, 21:51 »

Буст вообще не причем. Нужны два класса (хотя если захотеть, то хватит и одного): oarchive/iarchive, а внутри у них пусть будет QDataStream.
То есть так (создавая класс-прослойку) "лаконичнее" - напустились на бедный флажок Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #27 : Февраль 06, 2013, 21:52 »

Давайте так - поставьте конкретную задачу, типа hello, wold (можно сложнее). А я сделаю проект под qt для клиент/серверного приложения. Там и оцените затраты и размер писанного кода. Только не сегодня (результат), а то завтра вставать рано...
Я не прошу реализовывать, вопрос: как пушатся сложные объекты, например, коллекция объектов?
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #28 : Февраль 06, 2013, 21:54 »

То есть так (создавая класс-прослойку) "лаконичнее" - напустились на бедный флажок Улыбающийся
Так вам же его копипастить для сериализации 100500 полей сложных структур.
[off]Убивал бы за такие структуры. Улыбающийся[/off]

Плюс, в дальнейшем архивы легко расширяются: хочешь в xml, хочешь в json.... Улыбающийся
« Последнее редактирование: Февраль 06, 2013, 21:59 от Old » Записан
alexis031182
Гость
« Ответ #29 : Февраль 06, 2013, 22:06 »

Может всё-таки просто переопределять операторы << и >> (или вообще любые другие) у каждого класса/структуры, потребных к сериализации, а для вызова сериализации использовать шаблонный класс-контейнер. Если же нужны и простые типы, то просто специализации соответствующие добавить к этому классу. Так оно будет лучше, на мой взгляд. Во-первых, никто лучше не знает как сериализировать данные, нежели как тот объект класса, что ими владеет. Ну а во-вторых, контейнер - просто как единая точка входа/выхода получится.
Записан
Страниц: 1 [2] 3 4 ... 8   Вверх
  Печать  
 
Перейти в:  


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