Russian Qt Forum

Программирование => Общий => Тема начата: Susenin от Октябрь 31, 2013, 13:25



Название: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Susenin от Октябрь 31, 2013, 13:25
Добрый день!

У меня есть массив указателей на базовый класс некоторых объектов.

Код
C++ (Qt)
class Base
{
public:
   char a0;
   int b0;
   std::vector<long> c0;
};
 
class Derived1 : public Base
{
public:
   char a1;
   int b1;
   std::vector<long> c1;
};
 
class Derived2 : public Base
{
   char a2;
   int b2;
   std::vector<long> c2;
 
};
 
std::vector<Base *> a;
 

Нужно сохранить состояние вектора а в некотором текстовом файле, потом восстановить.
Иначе говоря, есть некие настройки в программе, их нужно сохранять.

Я реализовал это с помощью Boost.Serialization и все работало.

Но программа сейчас в процессе тестирования на объекте. Программист меняет классы Derived (добавляет/убирает переменные), соответственно файл настроек, созданный в предыдущей версии программы не открывается в последующей. Пользователей очень напрягает перезаводить кучу настроек.

Подскажите, пожалуйста, способ сериализации объектов в некий формат текстового файла, чтобы отсутствующие/новые поля обнулялись.
Пишу на Qt.


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: schmidt от Октябрь 31, 2013, 14:34
Добрый вечер,

Все же лучше будет, если этот ваш замечательный программист определится с окончательным набором переменных :) Насколько мне известно, ни в С++ ни в Qt нет адекватного способа обойти свойства/переменные объекта в цикле, как это делается c объектами в Javascript =)

Для сериализации объекта в файл прекрасно подойдет класс QDataStream - этакий аналог std::cout, только специально предназначенный для упаковки C++/Qt типов в поток двоичных данных.

Статья на Хабре про использование QDataStream: http://habrahabr.ru/post/150827/

Если двоичные файлы вам не по душе - к вашим услугам QSettings [http://doc.crossplatform.ru/qt/4.7.x/qsettings.html] - специально предназначен для того, чтобы хранить настройки вашего приложения в виде пар ключ/значение. По умолчанию хранит их в нативном формате (конфигурационные файлы на Unix/Linux, реестр на Win32).

//---------------------------------------------------------------------------------------

Если есть потребность перебирать все объекты в массиве и сохранять каждый из них, вам скорее подойдет QDataStream. Сериализовать объекты-наследники по указателям на базовый класс можно добавив к ним виртуальный метод serialize(QDataStream*).


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: m_ax от Октябрь 31, 2013, 15:24
Цитировать
Подскажите, пожалуйста, способ сериализации объектов в некий формат текстового файла, чтобы отсутствующие/новые поля обнулялись.
Пишу на Qt.

json? Конкретно для Qt, как вариант QJson


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Igors от Октябрь 31, 2013, 15:24
Все же лучше будет, если этот ваш замечательный программист определится с окончательным набором переменных :)
Эта ирония наивна, в процессе разработки сохраняемые данные мутируют часто, это нормально.

Насколько мне известно, ни в С++ ни в Qt нет адекватного способа обойти свойства/переменные объекта в цикле, как это делается c объектами в Javascript =)
Такой механизм есть (независимо от языка) и он используется очень широко. Называется простым словом "теги", часто также говорят IFF. Псевдокод
Код
C++ (Qt)
uint32 tag = stream.ReadUInt32();
uint32 size = stream.ReadUInt32();
switch (tag) {
case 'DATA':   // знаем этот тег
 ...
case 'OBJ1':   // и этот
 ...
 
default:
  stream.seek(stream.position() + size);   // неизвестные (возможно устаревшие) данные - пропускаем
}


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Old от Октябрь 31, 2013, 15:57
Называется простым словом "теги", часто также говорят IFF.
Человек просит текстовый формат для сохранения.

Подходит любой, для Qt самое простое это ini формат, через QSettings.
Подойдет и xml, в Qt тоже есть поддержка из коробки.
Есть JSON через внешний QJson.
Но я бы выбрал boost::property_tree, который может любой из выше перечисленных форматов. :)



Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: schmidt от Октябрь 31, 2013, 21:09
А в Qt5 поддержка JSON уже встроена :) http://qt-project.org/doc/qt-5.0/qtcore/json.html


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Igors от Октябрь 31, 2013, 21:22
Человек просит текстовый формат для сохранения.
А разве настоятельно рекомендуемый json текстовый? :) В текстовом формате то же самое (напр DXF и др), только длина не задается явно в байтах - но все равно есть начало и конец тега, поэтому ненужные теги можно пропустить 


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Old от Октябрь 31, 2013, 21:30
А разве настоятельно рекомендуемый json текстовый? :)
Да. Исключительно текстовый. Вот ссылка на секретную спецификацию: http://ru.wikipedia.org/wiki/JSON. Надеюсь на вашу порядочность.



Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Alex Custov от Октябрь 31, 2013, 21:46
В дополнение к JSON - Google Protocol Buffers


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Igors от Ноябрь 01, 2013, 11:18
Да. Исключительно текстовый. Вот ссылка на секретную спецификацию: http://ru.wikipedia.org/wiki/JSON. Надеюсь на вашу порядочность.
Насколько я помню - да, он состоит из читабельных символов. Но читать/редактировать его как ini не выйдет, да и концов строк в нем может не быть. Тогда "за что боролись"?  Возможно проще следовать IFF


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Old от Ноябрь 01, 2013, 11:59
Но читать/редактировать его как ini не выйдет, да и концов строк в нем может не быть.
Вы заблуждаетесь. Откройте уже ту секретную спецификацию на этот шайтан формат и прочтите. Почему вы опираетесь только на слухи и домыслы? :)


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Igors от Ноябрь 01, 2013, 12:08
Вы заблуждаетесь. Откройте уже ту секретную спецификацию на этот шайтан формат и прочтите. Почему вы опираетесь только на слухи и домыслы? :)
А зачем мне ее открывать? И так помню, неск лет назад писал для него парсер


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: Old от Ноябрь 01, 2013, 12:08
А зачем мне ее открывать? И так помню, неск лет назад писал для него парсер
;D


Название: Re: Как сериализовать объект в текстовой файл, чтобы неизвестные поля игнорировались
Отправлено: schmidt от Ноябрь 04, 2013, 11:15
А зачем мне ее открывать? И так помню, неск лет назад писал для него парсер
;D


 ;D