На этом шаге мы рассмотрим особенности сериализации классов, представляющих собой наборы.
В каждом из шаблонных классов-наборов MFC - CArray, CList и СМар - реализована собственная версия функции Serialize(), отвечающая за сериализацию любых элементов этого набора.
Предположим, что Ваш класс документа содержит следующий набор целочисленных значений:
CList<int, int &> m_intList;
Его можно сериализовать, добавив в Serialize() следующую строку:
m_intList. Serialize(ar);
Этого вполне достаточно для сериализации простых типов. CList::Serialize() обращается к шаблону глобальной вспомогательной функции SerializeElements(), описание которой имеет такой вид:
template<class TYPE> void AFXAPI SerializeElements(CArchive& ar, TYPE* pElements, int nCount);
Компилятор генерирует реализацию этого шаблона, соответствующую типу элементов набора. По умолчанию функция SerializeElements() переносит побитовую копию данных набора (на который указывает pElements) в или из места его хранения.
Такое поведение вполне годится для простых объектов, но не подходит для манипуляций с более сложными объектами. Представьте себе, что Ваш класс документа содержит такой член:
CList<CMyClass, CMyClass &> m_objList;
A CMyClass определен так:
сlass CMyClass { DECLARE_SERIAL(CMyClass) public: CMyClass() {;} int m_int; DWORD m_dw; CString m_string; virtual void Serialize(CArchive& ar); }
Попытка сериализации набора m_objList путем добавления приведенной ниже строки вызовет сбой:
m_objList.Serialize(ar);
Ошибка заключается в том, что объекты класса CMyClass содержат строки CStrings, представляющие собой сложные объекты с нестандартными методами выделения памяти и отсчета ссылок.
Функция SerializeElements() для набора m_objList, созданная по умолчанию, попытается считать или записать побитовую копию элементов набора в обход специальных процедур, встроенных в операторы << и >> класса CString.
В этом случае Вам придется создать собственную версию SerializeElements(). Если CMyClass должным образом поддерживает сериализацию, соответствующая SerializeElements() выглядит так:
template <> void AFXAPI SerializeElements <CMyClass> (CArchive& ar, CMyClass * pNewMC, int nCount) { for (int i = 0; i < nCount; i++, pNewMC++) { // Сериализируем каждый CMyClass-объект pNewMC->Serialize(ar); } }
Со следующего шага мы начнем рассматривать работу с реестром.