Хвост трубой! Шаг - взлет! Взгляд - навылет да окна - вдребезги!
Имеется мультисписок MultiList, где Shape - абстрактный класс "фигура", от которого наследуются классы "Прямоугольник", "Текс", а от них в свою очередь наследуется класс "Текст в прямоугольнике".
Соответственно, в мультисписок можно напихать всего и сразу по правилу подстановки.
Теперь возникла потребность мультисписок сериализовать и десериализовать.
Решено было использовать стандартные средства QT, т.е. QDataStream. С сериализацией все получается довольно просто, а вот с десериализацией у меня проблемы.
Как я понимаю, там требуется точно определить какой объект мы десериализуем, чтобы потом его вставить в список.
Как эту задачу решить, не знаю. Надеюсь на вашу помощь.

@темы: C++

Комментарии
06.10.2010 в 16:36

IDDQD - Команда молодости нашей, команда, без которой мне не жить.
А с помощью каких механизмов ты сериализуешься/десериализуешься?
06.10.2010 в 16:44

Хвост трубой! Шаг - взлет! Взгляд - навылет да окна - вдребезги!
Flex Ferrum
Если я правильно поняла вопрос...
Опиралась на эту статью
Там, конечно, для qt3, но в принципе ничего не изменилось.
Во всех классах (Rectangle, Text и RectangleWithText) переопределяется оператор << и >> для QDataStream.
И вот такие функции

пока оставила только прямоугольник, посмотрю, что будет. Но вопрос все равно открыт..
06.10.2010 в 19:28

Хвост трубой! Шаг - взлет! Взгляд - навылет да окна - вдребезги!
да, на то, что это мультисписок не смотрите. Считаем, что это обычный stl'евский список list.
07.10.2010 в 11:16

IDDQD - Команда молодости нашей, команда, без которой мне не жить.
Как я понимаю, там требуется точно определить какой объект мы десериализуем, чтобы потом его вставить в список. Как эту задачу решить, не знаю. Надеюсь на вашу помощь.
Решить задачу, на самом деле, не сложно. Тебе надо сделать следующее:
1. В базовом классе Shape определить виртуальные функции, которые будут перегружены в наследниках и корректным образом записывать состояние объектов в поток.
2. Там же (в базовом классе) определить виртуальную функцию (переопределяющуюся в наследнике), которая будет возвращать некий числовой идентификатор, описывающий конкретный класс.
3. Реализовать статический "виртуальный конструктор", который по идентификатору будет создавать нужного наследника от Shape.
4. Всё это дело использовать при сериализации и десериализации. Как-то так:

class Shape
{
public:
virual ~Shape() {;}
virtual void WriteToStream(QDataStream& str) const = 0;
virtual void ReadFromStream(QDataStream& str) = 0;
virtual int GetClassID() const = 0;

static Shape* Create(int id)
{
switch (id)
{
case Rectangle: return new Rectangle();
case RectangleWithText: return new RectangleWithText();
}
return NULL;
}
};

//...

// записываем:
void writeToStream(QDataStream &out, MultiList *list)
{
MultiList::multi_iterator it;
for (it = list->begin(); it != list->end(); it++)
{
out << it->GetID();
it->WriteToStream(out);
}
}

// читаем
void readFromStream(QDataStream &in, MultiList *list)
{
list->clear();

MultiList::multi_iterator it;

it = list->begin();

while (!in.atEnd()) {

int id;
in >> id;
Shape* shape = Shape::Create(id);
if (shape != NULL)
{
shape->ReadFromStream(in);
list->insert();
}

}
}


Общая логика такая. Можно улучшать (фабрику сделать абстрактной, идентифицировать классы по typeid, и т. п.), но общая схема останется такой же.
07.10.2010 в 15:04

Хвост трубой! Шаг - взлет! Взгляд - навылет да окна - вдребезги!
Flex Ferrum
Спасибо.
Попробую