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

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

Страниц: 1 2 3 [4] 5 6 ... 8   Вниз
  Печать  
Автор Тема: Сериализация (как сделать поудобнее)  (Прочитано 48189 раз)
alexis031182
Гость
« Ответ #45 : Февраль 07, 2013, 01:59 »

Жаль частичная специализация для функций не поддерживается. Так то наверное правильнее называть специализацию для функций перегрузкой, потому как она в принципе и получается, но всё равно, тоже работает:
Код
C++ (Qt)
template<class Stream, class T>
void ReadWrite(Stream &strm, T *data);
 
template<class Stream, class T, int>
void ReadWrite(Stream &strm, T *data) {
   qDebug() << 1;
}
 
template<class Stream, class T, int, int>
void ReadWrite(Stream &strm, T *data) {
   qDebug() << 2;
}

И собственно вызов:
Код
C++ (Qt)
int strm, data;
ReadWrite<int, int, 0>(strm, &data);
ReadWrite<int, int, 0, 0>(strm, &data);
Записан
alexis031182
Гость
« Ответ #46 : Февраль 07, 2013, 02:04 »

Вы когда закончите оценивать различные шаблонные, для меня непонятные технологии, предоставьте лучший вариант Улыбающийся

А ещё желательно с примерами в коде Веселый

PS заложите, так сказать, правильный подход к сериализации. А то у меня сериализация мозголомная в проекте, вон я тему создавал - наследие драконов прям Веселый
Я бы выбрал бустовский вариант. Буст сам тащить ни к чему, там в примерах вся идея с одним оператором и так показана, можно в собственном классе-шаблоне повторить.
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


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


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

Ну, наверное, можно придумать пример, который не впишется в мою схему. Но хотелось бы конкретики, желательно, из жизни. А вдруг, решаемо...
Есть любой std::map. Как его сериализовать таблицей, а главное как потом десериализовать?

Если в простом случае, когда ключ и значение сводится к классам с членами-данными стандартных типов (map<T1,T2>), то легко - две таблицы, одна передает T1, вторая T2. На приемной стороне ассоциативный массив "слепляется" из двух половинок.
В общем случае, нужна декомпозиция данных, приведение к стандартным типам и в цикле передача составных частей. На приемной стороне - обратное восстановление. Но в этом случае изменение структуры данных, параметризующих map, приведет к изменению и клиентской и серверной функции.
Я поэтому и говорил о конкретном примере, чтобы можно было оценить ограничение метода.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



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

PS заложите, так сказать, правильный подход к сериализации. А то у меня сериализация мозголомная в проекте, вон я тему создавал - наследие драконов прям Веселый

Так это смотря что сериализовать, как и куда Улыбающийся.

1. Если много простых, несвязанных между собой структур, да большинство из которых нельзя модифицировать, то надо смотреть в сторону способа как в QDataStream.
2. Все структуры ваши и можете делать с ними все, что угодно, то брать буст или сделать аналогично.
3. Как п. 2, структуры разрозненные, но есть возможность добавить им всем общего предка, то сравнить способ буста и способ sergek.
4. Классы хорошо организованы в иерархии, довольно громоздкие, в некоторых случаях требуют индивидуальной обработки полей и есть возможность добавить общего предка, то можно попробовать слепить такого странного монстра XMLContentReader/XMLContentWriter.

Соответственно, способ нужно выбирать под свои задачи, у каждого есть свои плюсы и минусы.

А с шаблонами лучше разобраться, штука очень мощная, может сильно уменьшить объем написания кода. Правда мозги при этом свернутся Веселый.
Записан

Пока сам не сделаешь...
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #49 : Февраль 07, 2013, 13:59 »

to sergek:
Ваш способ и есть тот камень преткновения. При изменении структуры, придётся переписывать функции send и receive.
Или я не уловил вашу систему и у вас сериализуются типы по их текстовому названию и вызывается соответствующий сериализатор?
Много ли у вас таких структур, что надо волноваться?
В моем проекте приходится поддерживать насколько форматов. Структуры там разные, их немало.
Проблемы конечно есть, но решил, что аккуратность будет от них лекарством.

При проектировании сериализации воспользовался механизмом наследования от абстрактного класса и патерном "посетитель":
Абстрактный класс спасает от "забывчивости", а посетитель позволяет сделать 1 раз обход документа разными сериализаторами, а детали сериализации скрыты в конкретных сериализаторах в нужных функциях. Я их писал рядышком парами: сохранение / считывание. Это позволяет визуально контролировать правильность.
Код:
/// Сохранение отчета. Инициализируем лоадер, вызываем сохранение...
bool uoReportDoc::saveToFile(QString path, uoRptStoreFormat stFormat, uoReportSelection* sel)
{
bool retVal = false;
if (stFormat == uoRsf_Unknown) {
qWarning() << tr("no define store format");
return false;
}
uoReportLoader* loader = uoReportLoader::getLoader(stFormat);
if (!loader) {
qWarning() << tr("Can not create loader"); return false;
}

loader->setFileName(path);
if (!loader->initFO(false)){
qWarning() << loader->getLastError();
} else {
flush(loader, sel);
}
loader->finalize();
delete loader;

return retVal;
}
« Последнее редактирование: Февраль 07, 2013, 14:05 от panAlexey » Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #50 : Февраль 07, 2013, 14:01 »

По поводу охов и ахов насчет буста
Код
C++ (Qt)
ar & g.degrees;
Значит вот это круто. А что бы Вы сказали если бы это написал велосипедист (который наверное ничего не знает)? Да Вы бы его охаяли с ног до головы Улыбающийся "Это что, интуититвный оператор & ? Да откуда я могу догадаться что он делает??". НО.. это великий дуст - и лояльность меняется на 180 градусов. "Ах как лаконично"  Улыбающийся

И собственно вызов:
Код
C++ (Qt)
int strm, data;
ReadWrite<int, int, 0>(strm, &data);
ReadWrite<int, int, 0, 0>(strm, &data);
Ну понеслась template-вакханалия  Улыбающийся Надо задрочить текст ну до полной невменяемости! Число typedef должно быть (намного) больше собственно кода. Это ж круто, вышак, типа "для избранных". А еще в этой пучине легко спрятать по существу слабенький функционал - кто там разберется за лесом шаблонов?
(Александр, мое мнение субъективно  Улыбающийся)

sergek, спасибо за предложение тестового примера, но тут "эффект большого" - на простом hello world вероятно любая схема успешно отработает. Если нетрудно покажите (или расскажите) что делает метод push. Из Вашего кода я не понял как же (используя что) разруливается I/O. Спасибо
Записан
Bepec
Гость
« Ответ #51 : Февраль 07, 2013, 14:05 »

Примерно десяток используемых сейчас и сотенки две на подходе. Улыбающийся

Это крупный проект, который почти загнулся от старости и поверх него кладут-кладут-кладут новые и новые кирпичики Улыбающийся

to Igors:
Я люблю понятливый код. Когда я в первый раз увидел бустовский функтор с сериализацией типов и полез внутрь я ошалел Улыбающийся Примерно десятка три макросов, шаблонов дофига и всё тяяяяяянется.

А используя <<  получаем наглядность, простоту (ну да, жертвуем короткой строкой, получаем сразу видимый для другого человека результат) и использование уже готовых гадостей решений.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

А используя <<  получаем наглядность, простоту (ну да, жертвуем короткой строкой, получаем сразу видимый для другого человека результат) и использование уже готовых гадостей решений.
Если устраивают просто операторы << и >>, то лучше пока ничего и не изобретать, решение должно идти "от жизни". 
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



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

По поводу охов и ахов насчет буста
Код
C++ (Qt)
ar & g.degrees;
Значит вот это круто.
Не это не круто. Круто было бы так:
Код
C++ (Qt)
ar <> g.degrees;
 
или так:
Код
C++ (Qt)
ar <<>> g.degrees;
 
Улыбающийся

А что бы Вы сказали если бы это написал велосипедист (который наверное ничего не знает)? Да Вы бы его охаяли с ног до головы Улыбающийся
Здесь буст прозвучал, только что бы показать, что можно совсем без доп. флагов, точнее архив сам этот флаг знает.
Если бы вы предложили решение без ненужного флага, то про буст вряд ли бы вспомнили. Подмигивающий
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



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

По поводу охов и ахов насчет буста
Код
C++ (Qt)
ar & g.degrees;
Значит вот это круто. А что бы Вы сказали если бы это написал велосипедист (который наверное ничего не знает)? Да Вы бы его охаяли с ног до головы Улыбающийся "Это что, интуититвный оператор & ? Да откуда я могу догадаться что он делает??". НО.. это великий дуст - и лояльность меняется на 180 градусов. "Ах как лаконично"  Улыбающийся
Не все в восторге от буста, но можно смотреть в таком разрезе, что люди там таки довольно много думали над проблемами и нашли не самые плохие способы их решения. А зачастую и самые лучшие в контексте поставленной задачи. Оператор &, шаблоны и макросы там не от хорошей жизни используют. Кстати, из-за обилия макросов мне этот буст и не нравится. Но Вы, когда будете развивать свой метод по объединению чтения/записи, верите или нет, наверняка придете к тому, что сейчас есть в бусте Улыбающийся. А сейчас там есть определение перечня полей, подлежащих сериализации. И ничего лишнего в самих структурах. Всем остальным занимаются отдельные сериализаторы, с помощью которых хоть в QDataStream, хоть в XML, хоть куда можно сохранять. Т.е. в структуру добавить что-нить типа:
Код
C
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
 ar & degrees;
 ar & minutes;
 ar & seconds;
}
и не надо больше никаких методов по вводу/выводу писать в каждой структуре. Вы же к этому и стремились: один раз описать поля и больше с ними не возиться Улыбающийся.

Это, опять же, не призыв этим способом пользоваться, и не возведение в абсолют буста, но как метод сериализации очень достоин внимания. Вы вполне можете сделать свой велосипед, который будет красивше и понятнее Улыбающийся.
Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #55 : Февраль 07, 2013, 14:48 »

Примерно десяток используемых сейчас и сотенки две на подходе. Улыбающийся

Это крупный проект, который почти загнулся от старости и поверх него кладут-кладут-кладут новые и новые кирпичики Улыбающийся

Тут вопрос такой: есть ли наследование в этих структурах, и поля-ссылки на другие структуры, в частности ссылка на базовый тип, когда фактически там может быть и производный объект?
Записан

Пока сам не сделаешь...
Bepec
Гость
« Ответ #56 : Февраль 07, 2013, 14:59 »

Все структуры взаимосвязаны.
Фактически они являются нодами огромнейшей системы. Каждая нода может ссылаться на данные, на другую ноду, быть объединённой с другой нодой. Имеются ноды различных типов, начиная от физ устройства, заканчивая виртуальными узлами. Собственно получается этакий чоООООрный круг. Что на самом деле не круг, а граф связей между ними Веселый

Да, ссылок может быть несколько Веселый
Записан
alexis031182
Гость
« Ответ #57 : Февраль 07, 2013, 15:08 »

По поводу охов и ахов насчет буста
Код
C++ (Qt)
ar & g.degrees;
Значит вот это круто. А что бы Вы сказали если бы это написал велосипедист (который наверное ничего не знает)?
Я бы его сразу зауважал Улыбающийся

Да Вы бы его охаяли с ног до головы Улыбающийся "Это что, интуититвный оператор & ? Да откуда я могу догадаться что он делает??". НО.. это великий дуст - и лояльность меняется на 180 градусов. "Ах как лаконично"  Улыбающийся
Хаять бы уж точно не стал. А вот то, что решение у буста весьма и весьма, тут вряд ли Вы станете спорить. Что Вам там интуитивно непонятно?

И собственно вызов:
Код
C++ (Qt)
int strm, data;
ReadWrite<int, int, 0>(strm, &data);
ReadWrite<int, int, 0, 0>(strm, &data);
Ну понеслась template-вакханалия  Улыбающийся
Ну раз речь зашла о шаблонах, так оно и вот... Улыбающийся

Надо задрочить текст ну до полной невменяемости! Число typedef должно быть (намного) больше собственно кода. Это ж круто, вышак, типа "для избранных". А еще в этой пучине легко спрятать по существу слабенький функционал - кто там разберется за лесом шаблонов?
(Александр, мое мнение субъективно  Улыбающийся)
Конечно субъективно Улыбающийся Непонятно только, что тут вызывает у Вас такой антагонизм. Ну шаблоны, ну typedef, ну не пользуйтесь, раз не нравится. Как бы свободу выбора, хотя бы в этом, пока ещё не отменяли Улыбающийся

А на самом деле, код на шаблонах очень красив, если делается с чувством, толком, расстановкой. Да, порог вхождения для понимания выше, но это же не значит, что это сразу плохо. И никто здесь грудь не выпячивает, мол, "я всех порвал, я на шаблонах прогаю". Просто идёт обсуждение различных подходов к проблеме сериализации. Вот и всё Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Если бы вы предложили решение без ненужного флага, то про буст вряд ли бы вспомнили. Подмигивающий
Почему ненужного? Возможно полезно явно видеть какая операция. Кстати а возможны ли др режимы кроме read/write? Может и да. Также мне лично куда приятнее имя ReadWrite чем абстрактный &.  К сожалению, обычно человеку "который много знает" копаться в этом неинтересно. "Там правильно" - значит все что "не так как там" - неправильно  Плачущий

и не надо больше никаких методов по вводу/выводу писать в каждой структуре. Вы же к этому и стремились: один раз описать поля и больше с ними не возиться Улыбающийся.
Так почему бы не сказать проще "используй сериализацию буста, там давно за тебя все сделали". Однако не все спешат это делать - хотя сериализация есть у каждого. Был слушок что там проблемы с версиями - правда никаких подробностей не знаю. Да и просто перелопатить с Archive множество живых классов как-то не тянет. Да, в Qt кое-чего нет, так что, сразу привлекать др либу? Может и свои решения будут неплохи (или такая мысль не допускается?  Улыбающийся)
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



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

Почему ненужного? Возможно полезно явно видеть какая операция.
Вы определитесь. То вы яростный противник копипаста, то большой сторонник. Улыбающийся
Передавать его в 100500 функций нет никакой необходимости, а если он понадобится, то его всегда можно спросить у архива.

К сожалению, обычно человеку "который много знает" копаться в этом неинтересно. "Там правильно" - значит все что "не так как там" - неправильно  Плачущий
К сожалению, не бывает так в программировании: там правильно, значит там не правильно. Грустный
А есть постоянный выбор, это удобней, это быстрей, это места меньше занимает, а это кроссплатформенно и много много такого.

Так почему бы не сказать проще "используй сериализацию буста, там давно за тебя все сделали".
Я почти во всех своих постах вынужден писать, что не нужно использовать сериализацию буста, а вот посмотреть удобный синтаксис и сделать так же у себя можно. Это просто. Захотите, что бы внутри был QDataStream - пожалуйста, захотите QDomDocument - да легко.
Страшно, что то предложить, все такие чувствительные. Что за комплексы? Улыбающийся
« Последнее редактирование: Февраль 07, 2013, 15:59 от Old » Записан
Страниц: 1 2 3 [4] 5 6 ... 8   Вверх
  Печать  
 
Перейти в:  


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