Ещё один подход к сериализации на С++
От: Сабельников Андрей Николаевич Россия  
Дата: 23.05.06 14:47
Оценка: 131 (8)
Статья:
Ещё один подход к сериализации на С++
Автор(ы): Сабельников Андрей Николаевич
Дата: 23.05.2006
“Вопросы сохранения данных из объектов, так или иначе, возникают у каждого разработчика”. Именно с этой фразы я начал первую статью посвещённую сериализации, и с этой фразы мне бы хотелось продолжить описание идеи использования карт для организации сериализации.
Если вы пишете на С++, то ваша программа скорее всего состоит из объектов классов, которые в своей совокупности образуют некую систему данных и кода, работающего с этими данныим. И практически всегда вы хотите в какой-то момент сохранить в том или ином виде эти данные – будь то результат многолетних вычислений программы или просто текущее состояние каких-то компонентов системы. А потом снова загрузить эти данные назад, в вашу программу, как будто бы и ничего не происходило. Или искажем отправить эти данные по сети, другой программе. И при этом, очень нехочетатся трартить много времени на программирование сохранения/загрузки, упаковку стрктур в каки-то изобретённые сегодня утром форматы, отладку всего этого, модификацию в связи с появлением в структурах данных новых полей, документирование, и прочую головную боль.
Подход, описаный ниже, я надеюсь, поможет многим сэкономить время и облегчить жизнь.


Авторы:
Сабельников Андрей Николаевич

Аннотация:
Если вы пишете на С++, то ваша программа скорее всего состоит из объектов классов, которые в своей совокупности образуют некую систему данных и кода, работающего с этими данныим. И практически всегда вы хотите в какой-то момент сохранить в том или ином виде эти данные — будь то результат многолетних вычислений программы или просто текущее состояние каких-то компонентов системы. А потом снова загрузить эти данные назад, в вашу программу, как будто бы и ничего не происходило. Или искажем отправить эти данные по сети, другой программе. И при этом, очень нехочется тратить много времени на программирование сохранения/загрузки, упаковку структур в какие-то изобретённые сегодня утром форматы, отладку всего этого, модификацию в связи с появлением в структурах данных новых полей, документирование, и прочую головную боль.
Подход, описаный ниже, я надеюсь, поможет многим сэкономить время и облегчить жизнь.
Re[2]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 08.07.06 20:13
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:


А>А чем boost::serialize не подошёл?



А>Каюсь, сам был грешен, использовал собственный велосипед под названием BrokerStorage — использование типа :


А>MyBrokerStorage <<SomeObject1 ;

А>MyBrokerStorage <<SomeObject2 ;
А>MyBrokerStorage >> SomeFormat;

А>В boost то же универсальное описание сериализации для всех классов, но нет промежуточного хранилища.

А>Делаете простенький переходничёк в свой формат, можете оптимизировать с учётом специфики.

А>Или я чего не понял?


Отвечу под анонимом т.к. пока не получается востановить паролъ.
Во первых — спасибо что просмотрели статью.

Постараюсь коротко и лаконично ответить на Ваш вопрос.

Сразу оговорюсь о терминологии — "хранилище"(в статье) и "архив"(в бусте) — обозначают одну и ту же сущность.

Что касается промежуточного хранилища — те же яйца только в профиль
Продемонстрированный в статье подход не обязывает вас использовать так называемый "промежуточный контейнер"(а именно вы наверное имели в виду временно загружаемые в память данные) — например в случае сериализации в реестр, никакие промежуточные данные не хранятся — все операции делигируются сразу в API операционной системы. Если вы хотите сохранять в сплошной кусок памяти именно моей реализации — тогда да, моя реализация хранилища(тот же архив — вид сбоку) предпологает раскручиваение древовидной структуры данных из упакованных структур в stl-ые ассоциативные массивы, что бы доступ по именам полей был быстрее и проще реализован.
Вы, если пожелаете, можете писать свою реализацию, оптимизируя по скорости/размеру если это актуально. Это вопрос организации хранилища(в бусте это обозначается терминов "архив").
А кроме того, точно так же в бусте вы создаёте "промежуточный экземпляр" архива:

//Пример из документации по бусту с http://www.boost.org/libs/serialization/doc/index.html      
std::ifstream ifs("filename", std::ios::binary);//Создаётся провайдер потока данных - в данном случае из файла
boost::archive::text_iarchive ia(ifs);//Создаётся такой же промежуточный объект-хранилище
// read class state from archive
ia >> newg;//Загрузка данных из архива


Отсюда позвольте перейти к сути Вашего вопроса. Почему не boost::serialization ?.

В бусте сохраняемые объекты представляются последовательным потоком. Т.е. там имеет значение последовательность элементов описанных в функции serialize(*).
В какой последовательности засунуты — в такой и высовываем. Как тока появляются разные версии, начинается самодеятельность с условными операторами:
//То же из примера с http://www.boost.org/libs/serialization/doc/index.html      
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        // only save/load driver_name for newer archives
        if(version > 0)
            ar & driver_name;
        ar & stops;
    }

А я нехочу тратить время на постоянное согласовывание форматов версий.
Ну и кроме того, чисто субъективно:
a) мне не нравится когда простые операторы в с++ значат нетривиальные вещи: оператор "&" перегружен, и вызывает "<<" или ">>" хотя на первый взгляд выглядит как объявление ссылки(без инициализации правда ).
b) мне больше нравится писать\смотреть карту сериализации, чем функцию — легче писать, легче читать и видеть иерархию, минуя путанницу условных операторов согласования версий.
Re: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 08.07.06 12:14
Оценка:
Здравствуйте, Сабельников Андрей Николаевич, Вы писали:

САН>Статья:

САН>Ещё один подход к сериализации на С++
Автор(ы): Сабельников Андрей Николаевич
Дата: 23.05.2006
“Вопросы сохранения данных из объектов, так или иначе, возникают у каждого разработчика”. Именно с этой фразы я начал первую статью посвещённую сериализации, и с этой фразы мне бы хотелось продолжить описание идеи использования карт для организации сериализации.
Если вы пишете на С++, то ваша программа скорее всего состоит из объектов классов, которые в своей совокупности образуют некую систему данных и кода, работающего с этими данныим. И практически всегда вы хотите в какой-то момент сохранить в том или ином виде эти данные – будь то результат многолетних вычислений программы или просто текущее состояние каких-то компонентов системы. А потом снова загрузить эти данные назад, в вашу программу, как будто бы и ничего не происходило. Или искажем отправить эти данные по сети, другой программе. И при этом, очень нехочетатся трартить много времени на программирование сохранения/загрузки, упаковку стрктур в каки-то изобретённые сегодня утром форматы, отладку всего этого, модификацию в связи с появлением в структурах данных новых полей, документирование, и прочую головную боль.
Подход, описаный ниже, я надеюсь, поможет многим сэкономить время и облегчить жизнь.


САН>Авторы:

САН> Сабельников Андрей Николаевич

САН>Аннотация:

САН>Если вы пишете на С++, то ваша программа скорее всего состоит из объектов классов, которые в своей совокупности образуют некую систему данных и кода, работающего с этими данныим. И практически всегда вы хотите в какой-то момент сохранить в том или ином виде эти данные — будь то результат многолетних вычислений программы или просто текущее состояние каких-то компонентов системы. А потом снова загрузить эти данные назад, в вашу программу, как будто бы и ничего не происходило. Или искажем отправить эти данные по сети, другой программе. И при этом, очень нехочется тратить много времени на программирование сохранения/загрузки, упаковку структур в какие-то изобретённые сегодня утром форматы, отладку всего этого, модификацию в связи с появлением в структурах данных новых полей, документирование, и прочую головную боль.
САН>Подход, описаный ниже, я надеюсь, поможет многим сэкономить время и облегчить жизнь.




А чем boost::serialize не подошёл?


Каюсь, сам был грешен, использовал собственный велосипед под названием BrokerStorage — использование типа :

MyBrokerStorage <<SomeObject1 ;
MyBrokerStorage <<SomeObject2 ;
MyBrokerStorage >> SomeFormat;

В boost то же универсальное описание сериализации для всех классов, но нет промежуточного хранилища.
Делаете простенький переходничёк в свой формат, можете оптимизировать с учётом специфики.

Или я чего не понял?
Re: Ещё один подход к сериализации на С++
От: siv Украина  
Дата: 08.07.06 20:25
Оценка:
ИМХО основной недостаток статьи — нераскрытие того, как всё же [де]сериализовать объекты по указателю [в контейнерах].
Re[2]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 08.07.06 21:06
Оценка:
Здравствуйте, siv, Вы писали:

siv>ИМХО основной недостаток статьи — нераскрытие того, как всё же [де]сериализовать объекты по указателю [в контейнерах].


А разве это не очевидно ?

N_SERIALIZE_POD               (*m_pguid_val, "m_guid_val")// Если у вас указатель - разыменовываем


Это то, что мы всегда делаем, когда у нас есть указатель а нужна ссылка.

Кроме того, если вы не уверенны, что Ваш указатель валиден, можно так:

//..............................
    N_SERIALIZE_POD               (m_dwrd_val, "m_dwrd_val")
    if(m_pguid_val)
        {N_SERIALIZE_POD               (*m_pguid_val, "m_guid_val")}
    N_SERIALIZE_STL_CONTAINER_POD (m_list_of_dwords, "m_list_of_dwords")
//...............................


Но, разумеется, это не является особенностью моей идеи — это синтаксис языка. Поэтому этого (и тому подобного) в статье нет.
Re[3]: Ещё один подход к сериализации на С++
От: siv Украина  
Дата: 09.07.06 15:07
Оценка:
А>А разве это не очевидно ?
Вопрос был с подвохом

А>
А>N_SERIALIZE_POD               (*m_pguid_val, "m_guid_val")// Если у вас указатель - разыменовываем
А>

Ok, этим мы запишем в "поток" содержимое объекта, на который указывал указатель в момент сериализации.
Теперь при десирализации мы должны сделать следующее (грубо):
— выделить память и сконструировать объект;
— десериализовать данный объект из "потока";
— если все Ok, проинициализировать член-указатель на готовый объект.
Т.о. имеется некоторая потребность в макросах типа
N_SERIALIZE_PTR_POD, N_SERIALIZE_PTR_T .

Но! Довольно часто встречается ситуция, когда на один и тот же объект имеются указатели из разных сериализуемых контейнеров. Следовательно приемлемый механизм сериализации должен предлагать механизмы по удобной (прозрачной) обработке подобных вещей. Например, сериализация в MFC делает это ценой некоторых накладных расходов...
В данной статье я и не увидел ничего, относящегося к вышеизложенному.

А>Это то, что мы всегда делаем, когда у нас есть указатель а нужна ссылка.


А>Кроме того, если вы не уверенны, что Ваш указатель валиден, можно так:

А>
А>//..............................
А>    N_SERIALIZE_POD               (m_dwrd_val, "m_dwrd_val")
А>    if(m_pguid_val)
А>        {N_SERIALIZE_POD               (*m_pguid_val, "m_guid_val")}
А>    N_SERIALIZE_STL_CONTAINER_POD (m_list_of_dwords, "m_list_of_dwords")
А>//...............................
А>


Не понял, каким образом это помогает установить валидность указателя
Re[4]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 09.07.06 19:34
Оценка:
Здравствуйте, siv, Вы писали:

А>>А разве это не очевидно ?

siv>Вопрос был с подвохом

А>>
А>>N_SERIALIZE_POD               (*m_pguid_val, "m_guid_val")// Если у вас указатель - разыменовываем
А>>

siv>Ok, этим мы запишем в "поток" содержимое объекта, на который указывал указатель в момент сериализации.
siv>Теперь при десирализации мы должны сделать следующее (грубо):
siv>- выделить память и сконструировать объект;
это ещё зачем ? можно десериализовывать в объект который уже существует на момент десериализации.
siv>- десериализовать данный объект из "потока";
siv>- если все Ok, проинициализировать член-указатель на готовый объект.
siv>Т.о. имеется некоторая потребность в макросах типа
siv>N_SERIALIZE_PTR_POD, N_SERIALIZE_PTR_T .
Так к сожалению и непонял необходимость этих макросов

siv>Но! Довольно часто встречается ситуция, когда на один и тот же объект имеются указатели из разных сериализуемых контейнеров. Следовательно приемлемый механизм сериализации должен предлагать механизмы по удобной (прозрачной) обработке подобных вещей. Например, сериализация в MFC делает это ценой некоторых накладных расходов...

siv>В данной статье я и не увидел ничего, относящегося к вышеизложенному.
Если у Вас в проекте ситуация с указателями на один и тот же объект из разных классов — определитесь, кто из них владеет объектом и включите в карту сериализации объект один раз именно там. В остальных классах он не должен входить в карту сериализации. IMHO это во первых на много лучше с точки зрения дизайна. Во вторых — такой интеллектуальный анализ, о котором Вы говорите, добавит избыточную сложность в описываемый подход.
А про сериализацию в MFC я вообще, даже разговаривать нехочу

А>>Это то, что мы всегда делаем, когда у нас есть указатель а нужна ссылка.


А>>Кроме того, если вы не уверенны, что Ваш указатель валиден, можно так:

А>>
А>>//..............................
А>>    N_SERIALIZE_POD               (m_dwrd_val, "m_dwrd_val")
А>>    if(m_pguid_val)
А>>        {N_SERIALIZE_POD               (*m_pguid_val, "m_guid_val")}
А>>    N_SERIALIZE_STL_CONTAINER_POD (m_list_of_dwords, "m_list_of_dwords")
А>>//...............................
А>>


siv>Не понял, каким образом это помогает установить валидность указателя

А самым, что ни на есть, элементарным — проверка на ноль. Если указатель куда-то указывает — щитаем что он валиден.
Доза паранои в работе с указателями никогда не повредит (случай когда у вас остаётся указатель, а сам объект уже удалён или когда указатель неинициализирован не рассматривается, т.к. это просто плохой стиль — сериализация тут непричём)
Re[5]: Ещё один подход к сериализации на С++
От: siv Украина  
Дата: 10.07.06 10:39
Оценка:
А>это ещё зачем ? можно десериализовывать в объект который уже существует на момент десериализации.
И каким волшебным образом он вдруг "уже существует".
Представь, у тебя в классе ну, например std::list< CMyClass*> m_container. Его нужно [де]сериализовать также удобно, как и остальные члены (т.е. с помощью карты и макросов).
В статье о сериализации подобного скромно умалчивается.

siv>>N_SERIALIZE_PTR_POD, N_SERIALIZE_PTR_T .

А>Так к сожалению и непонял необходимость этих макросов
Я забыл упомянуть еще эти:
N_SERIALIZE_STL_CONTAINER_PTR_POD, N_SERIALIZE_STL_CONTAINER_PTR_T...
Это не необходимость, а дополнительное удобство, делающее твоё решение более завершенным и готовым к употреблению


siv>>Но! Довольно часто встречается ситуция, когда на один и тот же объект имеются указатели из разных сериализуемых контейнеров. Следовательно приемлемый механизм сериализации должен предлагать механизмы по удобной (прозрачной) обработке подобных вещей. Например, сериализация в MFC делает это ценой некоторых накладных расходов...

siv>>В данной статье я и не увидел ничего, относящегося к вышеизложенному.
А>Если у Вас в проекте ситуация с указателями на один и тот же объект из разных классов — определитесь, кто из них
А>владеет
объектом и включите в карту сериализации объект один раз именно там.

Даже не рискну предположить, что ты о смарт-пойнтерах не слышал
Данный совет выглядит как-то уж слишком по-детски и совсем не решает проблемы.
Разные объекты одного и того же класса могут равноправно "шарить" одни и те же экземпляры объектов.
И как твой совет помогает восстановить такой граф (e.g. DAG) после десериализации?

А> В остальных классах он не должен входить в карту сериализации. IMHO это во первых на много лучше с точки зрения дизайна.

Дизайны разные бывают, что где-то лучше, в другом месте оно м.б. неприемлемо

А>Во вторых — такой интеллектуальный анализ, о котором Вы говорите, добавит избыточную сложность в описываемый подход.

Авторы MFC имели другое мнение...

А>А про сериализацию в MFC я вообще, даже разговаривать нехочу

Ну, на том и закончим.
MFC же я упомянул только как один из примеров реализации того аспекта, который отсутсвует в твоей имплементации Yet Another Serialization.
Re[6]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 10.07.06 11:40
Оценка:
Здравствуйте, siv, Вы писали:

А>>это ещё зачем ? можно десериализовывать в объект который уже существует на момент десериализации.

siv>И каким волшебным образом он вдруг "уже существует".
siv>Представь, у тебя в классе ну, например std::list< CMyClass*> m_container. Его нужно [де]сериализовать также удобно, как и остальные члены (т.е. с помощью карты и макросов).
siv>В статье о сериализации подобного скромно умалчивается.

Давайте разберёмся — сначала вы говорили о членах указателях, теперь о члене контейнере который хранит указатели. А это ужо другое. Скорее всего в списке хранятся указатели на базовый тип полиморфного объекта, даже если мы сможем сохранить данные из такого списка, через виртуальную функцию, каким образом мы сможем сконструировать объект при десериализации ? Тут появляется комбинаторное множество вариантов, для каждого из которых нужна будет специальная реализация. Если творить очередного монстра, то можно конечно связаться с пораждающими паттернами, связывать их с типами в Вашем проекте....но это IMHO просто ненужно в библиотеке сериализации — это можно сделать руками внутри вашего проекта, написать функцию сохранения\загрузки имея информацию о действительных о типах объектов.

siv>>>N_SERIALIZE_PTR_POD, N_SERIALIZE_PTR_T .

А>>Так к сожалению и непонял необходимость этих макросов
siv>Я забыл упомянуть еще эти:
siv>N_SERIALIZE_STL_CONTAINER_PTR_POD, N_SERIALIZE_STL_CONTAINER_PTR_T...
siv>Это не необходимость, а дополнительное удобство, делающее твоё решение более завершенным и готовым к употреблению
И настолько тяжеловесным, непонятным и непрозрачным, что никому не интересным

......
siv>Даже не рискну предположить, что ты о смарт-пойнтерах не слышал
siv>Данный совет выглядит как-то уж слишком по-детски и совсем не решает проблемы.
siv>Разные объекты одного и того же класса могут равноправно "шарить" одни и те же экземпляры объектов.
siv>И как твой совет помогает восстановить такой граф (e.g. DAG) после десериализации?
Никак.
А>> В остальных классах он не должен входить в карту сериализации. IMHO это во первых на много лучше с точки зрения дизайна.
siv>Дизайны разные бывают, что где-то лучше, в другом месте оно м.б. неприемлемо

А>>Во вторых — такой интеллектуальный анализ, о котором Вы говорите, добавит избыточную сложность в описываемый подход.

siv>Авторы MFC имели другое мнение...

А>>А про сериализацию в MFC я вообще, даже разговаривать нехочу

siv>Ну, на том и закончим.
siv>MFC же я упомянул только как один из примеров реализации того аспекта, который отсутсвует в твоей имплементации Yet Another Serialization.
MFC — не самый удачный пример В комапнии, в которй я сейчас работаю, у многих людей упоминание MFC вообще вызывает нервозность, в том числе эти ассоциации связаны с опытом использования архивов.

Уважаемый siv, Вы правы кое в чём — библиотека не умеет конструировать полиморфные объекты, из-за того, что не хранится никакой избыточной инофрмации и из-за того, что такая сложность нужна в редких случаях. Я решил исполнить максимально простую легковесную реализацию, что бы покрыть 90% потребностей большинства программистов.
С другой стороны я уверен что сериализация в MFC тоже не панацея от всего, и врятли можно найти библиотеку подходящую для всех типов задач.
Тем не мене спасибо что с интересом отнеслись к статье.
Re[5]: Ещё один подход к сериализации на С++
От: bnk СССР http://unmanagedvisio.com/
Дата: 10.07.06 12:17
Оценка:
Здравствуйте, Аноним, Вы писали:

siv>>Теперь при десирализации мы должны сделать следующее (грубо):

siv>>- выделить память и сконструировать объект;
siv>>- десериализовать данный объект из "потока";
siv>>- если все Ok, проинициализировать член-указатель на готовый объект.
siv>>Т.о. имеется некоторая потребность в макросах типа
siv>>N_SERIALIZE_PTR_POD, N_SERIALIZE_PTR_T .

А>это ещё зачем ? можно десериализовывать в объект который уже существует на момент десериализации.

А>Так к сожалению и непонял необходимость этих макросов

Это одно из стандартных требований к маханизму сериализации ( must have )
Необходимо для того, чтобы иметь возможность восстановить связи между объектами (указатели) в прочитанном наборе объектов(модели),
а также для динамического создания объектов в куче. Фактически, не имея данной возможности, механизм оказывается
неспособным сохранять/восстанавливать объекты, связанные с другими объектами. В упомянутых boost и MFC это реализовано.

Простые примеры:

// Пример1: Сохранить/восстановить объект класса Container, при условии что он может содержать объекты класса Base и объекты класса Derived?

class Base { int x; };
class Derived : public Base { int y; };
class Container { std::vector<Base*> m_items; };


// Пример2: Сохранить p, а потом восстановить ("ссылка на родителя")?

class Child  { Parent* parent; };
class Parent { Child child; };

Parent p;
p.child->parent = &p;


siv>>Но! Довольно часто встречается ситуция, когда на один и тот же объект имеются указатели из разных сериализуемых контейнеров. Следовательно приемлемый механизм сериализации должен предлагать механизмы по удобной (прозрачной) обработке подобных вещей. Например, сериализация в MFC делает это ценой некоторых накладных расходов...

siv>>В данной статье я и не увидел ничего, относящегося к вышеизложенному.

+1

А>Если у Вас в проекте ситуация с указателями на один и тот же объект из разных классов — определитесь, кто из них владеет объектом и включите в карту сериализации объект один раз именно там. В остальных классах он не должен входить в карту сериализации. IMHO это во первых на много лучше с точки зрения дизайна. Во вторых — такой интеллектуальный анализ, о котором Вы говорите, добавит избыточную сложность в описываемый подход.


К сожалению, это не всегда возможно. Точнее, это, как правило, возможно только для достаточно простых систем..
Если бы все было так просто, люди не придумывали бы всяких "умных указателей" и "сборщиков мусора".
IMHO, вообще, механизм, который не умеет восстанавливать связи между объектами (указатели), не стоит называть "сериализаций"...

А>А про сериализацию в MFC я вообще, даже разговаривать нехочу

Почему же?

Еще камешки. Все IMHO.

1. Ваши макросы, кажется, не работают для std::set, std::map (ассоциативных контейнеров).
2. push_back — не самая светлая идея для десериализации векторов... Это (а) медленно и (б) расточительно. resize() + индексация будет получше..
3. К чему все эти заморочки с разными типами строк ?!

Такая вот критика
Re[6]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 10.07.06 13:54
Оценка:
Спасибо, bnk, ты написал именно то, что я хотел сказать в соседнем мессадже, только ещё лучше

bnk>Еще камешки. Все IMHO.


Я добавлю еще один кирпичик.
Именование сохраняемых членов — фича понятная, в смысле версионности.
Но, ИМХО, довольно избыточная по объему сохраняемых данных.
Т.е. "КПД" может оказаться неприемлемо низким...
В общем предложенный механизм — не панацея
Re[7]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 10.07.06 13:56
Оценка:
А>Спасибо, bnk, ты написал именно то, что я хотел сказать в соседнем мессадже, только ещё лучше
Данный Аноним — это siv.
Re[7]: Ещё один подход к сериализации на С++
От: siv Украина  
Дата: 10.07.06 14:22
Оценка:
А>Давайте разберёмся — сначала вы говорили о членах указателях, теперь о члене контейнере который хранит указатели. А это ужо другое.
Сначала я намекал на недостатки статьи. потом усугубил. Сути это не меняет.

А> Скорее всего в списке хранятся указатели на базовый тип полиморфного объекта, даже если мы сможем сохранить данные из такого списка, через виртуальную функцию, каким образом мы сможем сконструировать объект при десериализации ? Тут появляется комбинаторное множество вариантов, для каждого из которых нужна будет специальная реализация. Если творить очередного монстра, то можно конечно связаться с пораждающими паттернами, связывать их с типами в Вашем проекте....но это IMHO просто ненужно в библиотеке сериализации — это можно сделать руками внутри вашего проекта, написать функцию сохранения\загрузки имея информацию о действительных о типах объектов.


В списке могут храниться указатели и на конкретный класс и на базовый. Не суть.
Важно то, что предложенный механизм не решает данную проблему НИКАК.
MFC и boost решают.

siv>>Это не необходимость, а дополнительное удобство, делающее твоё решение более завершенным и готовым к употреблению

А>И настолько тяжеловесным, непонятным и непрозрачным, что никому не интересным
Уже одного меня достаточно, чтобы слово "никому" было здесь не уместно

А>MFC — не самый удачный пример В комапнии, в которй я сейчас работаю, у многих людей упоминание MFC вообще вызывает нервозность, в том числе эти ассоциации связаны с опытом использования архивов.


Это не аргумент. В компании, на которую я сейчас работаю, испорльзование boost не разрешено И что?
И вообще, подобные заявления о нервозности я уже много раз слышал и о MFC и о COM и о C++ и о шаблонах и об указателях и о garbage collector...
Не удивлюсь, что скоро услышу подобное о .Net, С# 1.0, потом 2.0, окошках без 3D наворотов, ЭЛТ мониторах, мышах с ball и пр.

А>Уважаемый siv, Вы правы кое в чём

Угу, на абсолют никогда не претендовал И давайте по форумски на "ты", Ок?

А> — библиотека не умеет конструировать полиморфные объекты, из-за того, что не хранится никакой избыточной инофрмации и из-за того, что такая сложность нужна в редких случаях. Я решил исполнить максимально простую легковесную реализацию, что бы покрыть 90% потребностей большинства программистов.


Да, вот именно за легковестность я и поставил статье +1
А насчет редкости таких случаев — не согласен. У меня, как раз, наоборот.

А>С другой стороны я уверен что сериализация в MFC тоже не панацея от всего, и врятли можно найти библиотеку подходящую для всех типов задач.

Есссно!
Но уж если сериализовать, то сериализовать до конца! Т.е. и по указателям тоже must have.
Re[8]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 10.07.06 14:49
Оценка:
Здравствуйте, siv, Вы писали:

......
siv>В списке могут храниться указатели и на конкретный класс и на базовый. Не суть.
siv>Важно то, что предложенный механизм не решает данную проблему НИКАК.
siv>MFC и boost решают.
Я кстати не в курсе, каким образом буст решает данную проблему ? Мне просто интересно, если вас незатруднить пояснить.

siv>Это не аргумент. В компании, на которую я сейчас работаю, испорльзование boost не разрешено И что?

Вы не поверите, у нас тоже нельзя было но потом таки удалось убедить руководство использоватьв некоторых проектах.
Re[9]: Ещё один подход к сериализации на С++
От: bnk СССР http://unmanagedvisio.com/
Дата: 10.07.06 16:17
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, siv, Вы писали:


А>......

siv>>В списке могут храниться указатели и на конкретный класс и на базовый. Не суть.
siv>>Важно то, что предложенный механизм не решает данную проблему НИКАК.
siv>>MFC и boost решают.
А>Я кстати не в курсе, каким образом буст решает данную проблему ? Мне просто интересно, если вас незатруднить пояснить.

Принцип один, что в boost, что в MFC..
Во-первых, составляется "реестр известрых науке классов", с функциями генерации объектов. В MFC это делается с помощью CRunTimeClass, в boost- через шаблоны.
При сохранении определяется ТОЧНЫЙ класс записываемого полиморфного объекта (в MFC — через тот же CRunTimeClass, в boost вроде через typeid),
и в файл записывается некая ссылка на него ("GUID"). После этой "преамбулы" выполняется собственно сохранение полей класса.
При чтении, читается "преамбула", по "GUID"-у определяется, что за объект мы прочитали, находится в "реестре" соответствующий ему класс,
и вызывается соответствующая функция для создания объекта. После этого вызывается загрузка полей для даннго класса.
как-то примерно так...

с указателями на объекты есть свои заморочки (а особенно с "умными", типа boost::shared_ptr)... В общем, лучше смотреть оригинал
Serializable Concept
Re[6]: Ещё один подход к сериализации на С++
От: Аноним  
Дата: 10.07.06 20:05
Оценка:
Здравствуйте, bnk, Вы писали:


......<skiped>......
bnk>1. Ваши макросы, кажется, не работают для std::set, std::map (ассоциативных контейнеров).
Не работают — об этом написанно в статье.(не работают т.к. не представляется возможным написать единообразную функцию работы с последовательными контейнерами и с ассоциативными), хотя было бы удобным иметь такую возможность. Возможно я придумаю на этот счёт что-то в дальнейшем.
bnk>2. push_back — не самая светлая идея для десериализации векторов... Это (а) медленно и (б) расточительно. resize() + индексация будет получше..
Согласен, но это будет получше только для векторов — для списка это не скомпилируется, а делать частичные специализации — это поиметь проблемы с VC6. К тому же эта вечная страсть всё оптимизировать там где это нужно и ненужно часто только пустая трата времени(не всегда конечно), т.к. выигрыш в производительности настолько незаметный что никто и неоченит .
bnk>3. К чему все эти заморочки с разными типами строк ?!
К тому, что функции доступа\присваивания у них разные(у stl и у ATL\WTL\MFC), а перегрузить я немогу т.к. внесу ненужные дополнительные зависимости типов.

bnk>Такая вот критика

Спасибо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.