Сериализация нестандартных объектов при работе с файлами (Лабораторная работа № 18 по VISUALC++ 2005), страница 2

        return FALSE;

    about_dog.clear();

    UpdateAllViews(NULL);

    // TODO: add reinitialization code here

    // (SDI documents will reuse this document)

return TRUE;

}

Первая из них – вызов функции clear() класса CDog. Метод UpdateAllViews(NULL)информирует все виды, связанные с документом, что этот документ был модифицирован.

          Теперь  непосредственно займемся сериализацией. Для этого сначала  нужно обеспечить сериализацию объектов класса СDog. А значит, нужно в класс СDog добавить метод Serialize. С этой целью нужно выделить класс CDog, вызвать контекстное меню и в нем – Add/Add Function. В открывшемся окне ввести  функцию void virtual Serialize(CArchive& ar) .  В ней сериализировать элемент данных этого класса m_poroda. В результате функция имеет вид

void CDog::Serialize(CArchive& ar)

{

    CObject::Serialize(ar);

    if(ar.IsStoring())

        ar<<m_poroda;

    else

        ar>>m_poroda;

}

Кроме функции Serialize() нужно добавить два макроса. В описание класса CDog (конкретно в файл Dog.h) нужно вставить макрос

DECLARE_SERIAL(CDog). Он может   находиться где угодно, но в пределах описания класса, например,

class CDog : public CObject

{

    DECLARE_SERIAL(CDog)//Здесь точка с запятой не //нужны поскольку это вызов макроса , а не оператор С++

………………………………………………………………..

…………………………………………………………………..

};

          Аргументом макроса является имя созданного пользователем нестандартного класса (CDog). Макрос поддерживает информацию об этом  классе во время выполнения, а также обеспечивает динамическое создание объектов и их сериализацию.

          Ещё один макрос IMPLEMENT_SERIAL() следует разместить в файле Dog.cpp. Он может находиться как в начале, так и в конце файла. Удобнее всего размещать его в первой строке непосредственно после директив #include препроцессора.

          Макрос IMPLEMENT_SERIAL(CDog, CObject, 0) имеет три аргумента: имя класса, имя непосредственного базового класса и беззнаковое 32- разрядное целое, идентифицирующее номер схемы или номер версии вашей программы. Этот номер схемы позволяет защитить процесс сериализации от проблем, которые могут возникнуть, если вы пишете объекты в одной версии программы, а читаете в другой, в которой классы могут отличаться. Если вы последовательно модифицируете определение класса, то должны при этом изменять номер схемы. Если программа попытается прочитать данные, которые были записаны с номером схемы, отличным от номера текущей активной программы, возбуждается исключение.

          Чтобы выполнить сериализацию объекта  about_dog, являющегося элементом данных класса CMyDoc, следует вызвать его метод Serialize() внутри метода Serialize() документа CMyDoc.

void CMyDoc::Serialize(CArchive& ar)

{

    about_dog.Serialize(ar);

    /*if (ar.IsStoring())

    {

        // TODO: add storing code here

    }

    else

    {

        // TODO: add loading code here

}*/

}

          Следует заметить, что класс CObject  может  быть непрямым базовым классом. В частности это относится к иерархии классов, когда для класса самого высокого уровня CObject является непосредственным базовым классом, а для остальных – непрямым. Для корректной работы сериализации каждый класс в иерархии должен иметь добавленный макрос сериализации в классе верхнего уровня.

          Ваша программа готова. После её запуска нужно ввести породу собаки и затем записать в файл по File->Save As. Вызвать File->New и очистить экран. После этого прочитать из файла ранее записанную в него строку символов.

3 Контрольные вопросы

1 Что такое сериализация и зачем она  нужна?

2Какие макросы должны быть добавлены в сериализируемый нестандартный класс и где они должны размещаться?

3 Какой вид имеет функция Serialize() для нестандартного класса?

4 Что должно быть в функции Serialize() класса «Документ»?

5 Что делает метод Invalidate()?

6 Зачем нужен метод SetModifiedFlag()?

7 Что происходит при выполнении функции  UpdateAllViews(NULL)?

Список литературы

1 Айвор Хортон  VISUAL C++ 2005 Базовый курс, «Диалектика», Москва*Санкт-Петербург*Киев , 2007г.

2 Сергеев А.П., Терен А.Н. Программирование в VISUAL C++ 2005 «Диалектика», Москва*Санкт-Петербург*Киев , 2006г.

3 С. Холзнер Visual C++ 6, «ПИТЕР», Санкт-Петербург* Москва*Харьков*Минск, 2001г.