Визуальное программирование и MFC

       

Создание класса, обеспечивающего сериализацию данных


Библиотека классов MFC определяет механизм записи и восстановления объектов (serialization), причем поддержка этого механизма осуществляется средствами класса CObject.

Классы, наследованные от CObject, также могут обеспечивать работу механизма записи и восстановления объектов. Для этого при объявлении класса надо указать макрокоманду DECLARE_SERIAL, а при определении - макрокоманду IMPLEMENT_SERIAL.

Макрокоманду DECLARE_SERIAL необходимо поместить в описании класса во включаемом файле. Непосредственно после этой макрокоманды надо указать имя класса

DECLARE_SERIAL (имя_класса)

Макрокоманду IMPLEMENT_SERIAL следует указать перед определением класса в файле исходного текста приложения. Прототип макрокоманды IMPLEMENT_SERIAL представлен ниже:

IMPLEMENT_SERIAL (имя_класса, имя_базового_класса, номер_версии)

Параметр имя_класса определяет имя класса, имя_базового_класса - имя базового класса, из которого непосредственно наследуется класс. Последний параметр номер_версии - это число типа UINT, определяющее версию программы. Если разрабатывается новая версия приложения и изменяется набор данных, которые необходимо записать в файл, нужно изменить значение параметра номер_версии.

В классе должны быть определены специальные методы для записи и восстановления состояния объектов этого класса. Обычно эти методы сохраняют и восстанавливают элементы данных из класса. Таким образом, объекты класса сами отвечают за то, как они сохраняют и восстанавливают свое состояние.

Методы, сохраняющие и восстанавливающие объектов, взаимодействуют с объектом класса CArchive, который осуществляет непосредственную запись и чтение информации из файла на диске.

Класс CObject содержит виртуальный метод Serialize, отвечающий за запись и чтение объектов классов, наследованных от класса CObject:

virtual void Serialize(CArchive& ar);

В качестве параметра ar методу передается указатель на объект класса CArchive, используемый для записи и восстановления состояния объекта класса CObject (или наследуемого от него класса).
Чтобы узнать, какую операцию должен выполнить метод Serialize, необходимо воспользоваться методами IsLoading или IsStoring класса CArchive.

Итак, при создании нового класса, в котором метод Serialize применяется для сериализации данных, необходимо:

  • Чтобы класс был производным от класса CObject или его потомков.


  • При объявлении класса необходимо вставить макрокоманду DECLARE_SERIAL.


  • Определить в классе функцию Serialize, отвечающую за хранение переменных класса.


  • Определить в классе конструктор без параметров. Это может быть защищенный конструктор, если он вызывается только процесса сериализации данных. В конструкторе возможно динамическое создание объектов и инициализация переменных, если это необходимо.


  • Объявить в классе деструктор, если требуется выполнить специальные действия при разрушении объектов класса, например, освободить память динамически созданных объектов.


  • При реализации класса в начало файла реализации вставить макрос IMPLEMENT_SERIAL. У этой макрокоманды три параметра: имя класса, имя базового класса и номер версии формата файла, хранящего документ. Можно иметь несколько модификаций документа и с каждой из них связать свою версию.


  • Приведем шаблон (заготовку) файлов определения и реализации класса, который обеспечивает процесс сериализации данных:

    // фрагмент файла определения класса class CMyDoc:public CObject { DECLARE_SERIAL(CMyDoc) protected: virtual void Serialize(CArchive& ar); protected: CMyDoc(); protected: ~CMyDoc(); // другие описания класса ........................ };

    // фрагмент файла реализации класса IMPLEMENT_SERIAL(CMyDoc, CObject,1) CMyDoc::CMyDoc() { // здесь возможно динамическое создание объектов и // инициализация переменных, если это необходимо ………… } CMyDoc::~CMyDoc() { // здесь возможно выполнение специальных действий // при разрушении объектов класса, например, // освобождение памяти динамически созданных объектов ……… } void CMyDoc::Serialize(CArchive& ar) { if(ar.Storing()) { // здесь следует добавить код для записи переменных в архив ……… } else { // здесь следует добавить код для чтения переменных из архива, ……… } // здесь следует добавить вызовы методов Serialize для переменных // класса CMyDoc, являющихся объектами классов, // имеющих собственные методы Serialize } // другие методы класса .......................


    Содержание раздела