Программирование на Visual C++. Архив рассылки | страница 4
Первая пара макросов — это DECLARE_DYNAMIC|IMPLEMENT_DYNAMIC. С помощью включения этих макросов в код вашего класса вы можете включить одну из базовых функций CObject — способность узнавать класс объекта прямо во время выполнения программы. Для этого вы можете пользоваться функцией IsKindOf() в связке с макросом RUNTIME_CLASS, который возвращает указатель на структуру CRuntimeClass (где хранится вся информация о классе: имя, размер, версия, информация о базовом классе, указатель на конструктор объекта и т.д.)
Следующая пара — DECLARE_DYNCREATE|IMPLEMENT_DYNCREATE аналогична первой, но к возможности получать информацию о классе добавляется еще и возможность создавать объекты этого класса во время выполнения.
Объект создается функцией CreateObject структуры CRuntimeClass. Вот пример:
>CRunTimeClasspClass = RUNTIME_CLASS(СMyObject);
> // получаем ук-ль на структуру CRunTimeClass
>CObjectpNewObject= pClass->CreateObject();
> // создаем новый объект нужного класса
>ASSERT(pNewObject->IsKindOf(RUNTIME_CLASS(CMyObject));
> // проверяем класс объекта
И, наконец, мы подошли к последней паре макросов DECLARE_SERIAL| IMPLEMENT_SERIAL. Преобразование в последовательную форму и обратно — сериализация — дает программисту возможность сохранения и восстановления объектов. Для того, чтобы воспользоваться этой возможностью, в классе-наследнике нужно перекрыть виртуальную функцию Serialize().
Из нее обязательно нужно сначала вызвать родительскую версию. Одна и та же функция используется как для сохранения, так и для восстановления объекта. Какую операцию нужно произвести, она определяет из своего единственного параметра ar типа CArchive. Вот пример:
>void CMyObject::Serialize(CArchive ar) {
> CObject::Serialize(ar); // вызываем версию базового класса
> if (ar.IsStoring()) // если сохраняем,
> {
> ar << something; // то сохранить что-то
> } else // а иначе
> {
> ar >> something; // восстановить
> }
>}
Заметьте, что DECLARE_SERIAL|IMPLEMENT_SERIAL помимо сериализации включают и те возможности, которые дают две первые пары — это естественно, ведь если вы восстанавливаете объект, то вам понадобится возможность создать его во время выполнения программы. Например, приложению нужно сохранять и восстанавливать некоторый набор объектов различного типа. А для вызова соответствующего конструктора при восстановлении объекта нужно знать его тип. Механизм сериализации сохраняет информацию об объекте вместе с теми данными, что вы записываете явно в функции Serialize().