Сериализация классов-наборов 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.

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



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий