![]() |
|
|
![]()
|
|
| RobinHoodPHD |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 78 Регистрация: 12.8.2007 Где: Русь Репутация: нет Всего: 2 |
Доброго времени суток, Господа!
Продолжаю свое мытарство с программой для рисования
Где ObjectList - это экземпляр CObList хранящий мои фигуры. Каждая фигура представлена классом, производным от абстрактного класса Geom, который сам наследует от CObject; Вот такая иерархия: CObject Geom (абстрактный) RCircle, RLine, RRect, ... RDot - это классы моих фигур Для каждого класса фигуры я переопределил функцию Serialize, например для класса класса RCircle:
Класс описан с макросом DECLARE_SERIAL(RCircle) и в реализации есть IMPLEMENT_SERIAL(RCircle, CObject, 1) Сохранять - вроде сохраняет, по крайней мере строка el->Serialize (ar); вызывает функцию Serialize именно для RCircle. Проблема теперь с тем, как это прочитать. Ведь я не знаю какого типа я читаю объект - окружность, линию или чего еще. Кусок кода из CSDI1Doc::Serialize для чтения явно у меня не задался )) и не работает.
Во-первых цикл ни разу не прокручивается => буфер всегда пустой, хотя я вроде сериализовал 3 окружности и сам файл не нулевого размера. В общем вопрос - что я сделал не так, и что мне исправить, чтобы сохранить и восстановить мои объекты. Заранее благодарен за Ваши ответы на мое, немного сумбурное, и путанное изложение проблемы) |
||||||
|
|||||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Разумеется, перед телом объекта нужно писать его тип. Это можно делать самому или довериться MFC: если для объекта определить макрос DECLARE_SERIAL \ IMPLEMENT_SERIAL, то объект будет сериализоваться сам. Конечно, это не означает, что для абстрактного указателя модно вызвать Serialize, и он каким-то чудом превратится в объект нужного типа (я имею в виду загрузку). Не помню, как это именно происходит в MFC, но схема примерно такая: как я уже говорила, перед телом объекта обязательно записывается его тип - в виде числа или в виде строки, да хоть GUID - на что фантазии хватит. Далее, реализуется фабрика, которая принимает поток (архив) и возвращает объект. Фабрику можно реализовать как отдельный объект, либо как функцию. Если особых наворотов не требуется, то я бы ограничилась статической функцией. Тогда чтение будет выглядеть примерно так:
Ну, switch - это, конечно, если совсем лениво или иерархия объектов простая как тапок и не предполагает развития. Лучше делать объекты само-регистрирующимися. Собственно, DECLARE_SERIAL примерно так и действует. Подробностей не помню, т.к. в свое время мне что-то там не понравилась, и я предпочитаю организовывать фабрики сама. Но суть одна. -------------------- ... |
|||
|
||||
| RobinHoodPHD |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 78 Регистрация: 12.8.2007 Где: Русь Репутация: нет Всего: 2 |
Спасибо огромное, Earnest !! Так и сделал - работает как часы.
Единственное что не работает- это ar.IsBufferEmpty () - всегда возвращает false, поэтому я просто переделал так:
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Просто эта функция делает не то, что ты полагаешь.
Я обычно проверяю конец чтения просто по факту непрочтения очередной порции байтов: перед чтением каждого объекта ведь нужно прочесть его тип. Получается как-то так: if (ar.Read (&type, sizeof(type) != sizeof(type)) -> приплыли. Ну, и разумеется, try-catch не помешает для аварийных ситуаций (порча файла и т.д.) -------------------- ... |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |