Запись и восстановление объектов
Одна из задач, решаемых программистом при разработке приложений, которые могут создавать и редактировать документы различных типов, например текстовые или графические, заключается в том, чтобы предоставить пользователю возможность записать внутреннее представление документа в файл и восстановить его.
Чтобы облегчить программисту решение этой задачи, библиотека классов MFC определяет механизм записи и восстановления объектов (serialization). Поддержка механизма записи и восстановления объектов осуществляется средствами класса CObject.
Классы, наследованные от CObject также могут обеспечивать работу механизма записи и восстановления объектов. Для этого при объявлении класса надо указать макрокоманду DECLARE_SERIAL, а при определении – макрокоманду IMPLEMENT_SERIAL.
Макрокоманду DECLARE_SERIAL надо поместить перед описанием вашего класса во включаемом файле. Непосредственно после имени макрокоманды надо указать имя класса – class_name:
DECLARE_SERIAL(class_name)
Макрокоманду IMPLEMENT_SERIAL надо указать перед определением класса в файле исходного текста приложения, имеющего расширение CPP. Прототип макрокоманды IMPLEMENT_SERIAL представлен ниже:
IMPLEMENT_SERIAL(class_name, base_class_name, wSchema)
Параметр class_name определяет имя вашего класса, base_class_name – имя базового класса из которого непосредственно наследуется ваш класс. Последний параметр wSchema – это число типа UINT, определяющее версию программы. Если вы разработаете новую версию своего приложения и измените набор данных, которые необходимо записать в файл, измените параметр wSchema.
В классе должны быть определены специальные методы для записи и восстановления состояния объектов этого класса. Обычно эти методы сохраняют и восстанавливают элементы данных из класса. Таким образом, объекты класса сами отвечают за то, как они сохраняют и восстанавливают свое состояние.
Методы, сохраняющие и восстанавливающие состояние класса, взаимодействуют с объектом класса CArchive, который осуществляет непосредственную запись и чтение информации из файла на диске.
Класс CObject содержит виртуальный метод Serialize , отвечающий за запись и чтение объектов классов, наследованных от класса CObject:
virtual void Serialize(CArchive& ar) throw(CMemoryException) throw(CArchiveException) throw(CFileException);
В качестве параметра ar, методу передается указатель на объект класса CArchive , используемый для записи и восстановления его состояния из файла. Чтобы узнать, какую операцию должен выполнить метод Serialize, воспользуйтесь методами CArchive::IsLoading или CArchive::IsStoring.
Новая реализация метода Serialize должна первым делом вызвать метод Serialize базового класса. Это гарантирует, что при сохранении и восстановлении объекта будут обработаны все элементы всех базовых классов.
Метод Serialize вызывается объектами класса CArchive когда приложение читает или записывает этот объект, вызывая методы CArchive::ReadObject или CArchive::WriteObject. Сразу отметим, что с методами CArchive::ReadObject и CArchive::WriteObject непосредственно связаны операторы записи << и чтения >>.
Перед тем как создать объект класса CArchive, необходимо создать объект класса CFile. Связывая с объектом CFile файл на диске, имейте в виду, что если вы желаете записать объект файл, то файл надо открыть на запись, а если надо считать файл с диска и загрузить из него данные в объект, открыть файл надо для чтения.
Конструктор класса CArchive имеет следующий вид:
CArchive(CFile* pFile, UINT nMode, int nBufSize = 512, void* lpBuf = NULL) throw(CMemoryException, CArchiveException, CFileException);
Параметр pFile должен содержать указатель на объект класса CFile, из которого будут считываются или записываться данные. Перед вызовом конструктора файл, связанные с объектом pFile должен быть уже открыт.
Параметр nMode определяет, будут данные записываться в файл или считываться из него. Параметр nMode может принимать одно из трех значений CArchive::load, CArchive::store или CArchive::bNoFlushOnDelete, описанных в следующей таблице.