Шаг 90.
Среда программирования Visual C++.
Сериализация классов-наборов MFC

    На этом шаге мы рассмотрим особенности сериализации классов, представляющих собой наборы.

    В каждом из шаблонных классов-наборов 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); 
  } 
}


    Замечание. Для простого набора CString-объектов создавать отдельную версию SerializeElements() не нужно - MFC автоматически сделает это в исходном тексте CArchive.

    Со следующего шага мы начнем рассматривать работу с реестром.




Предыдущий шаг Содержание Следующий шаг