Armazenando e carregando CObjects por meio de um arquivo morto

Armazenar e carregar CObjects por meio de um arquivo morto requer consideração extra. Em determinados casos, você deve chamar a função Serialize do objeto, em que o objeto CArchive é um parâmetro da chamada Serialize, em vez de usar o operador << ou >> do CArchive. O fato importante a ter em mente é que o operador CArchive>> constrói CObject na memória com base nas informações CRuntimeClass gravadas anteriormente no arquivo pelo arquivo de armazenamento.

Portanto, se você usa os operadores CArchive<< e >> operadores, em vez de chamarSerialize, depende de se você precisa do arquivo de carregamento para reconstruir dinamicamente o objeto com base nas informações CRuntimeClass armazenadas anteriormente. Use a função Serialize nos seguintes casos:

  • Ao desserializar o objeto, você sabe a classe exata do objeto com antecedência.

  • Ao desserializar o objeto, você já tem memória alocada para ele.

Cuidado

Se você carregar o objeto usando a função Serialize, também deverá armazenar o objeto usando a função Serialize. Não armazene usando o operador CArchive<< e carregue usando a função Serialize ou armazene usando a função Serialize e carregue usando o operador CArchive >>.

O seguinte exemplo ilustra os casos:

class CMyObject : public CObject
{
   // ...Member functions
public:
   CMyObject() {}
   virtual void Serialize(CArchive &ar);

   // Implementation
protected:
   DECLARE_SERIAL(CMyObject)
};

class COtherObject : public CObject
{
   // ...Member functions
public:
   COtherObject() {}
   virtual void Serialize(CArchive &ar);

   // Implementation
protected:
   DECLARE_SERIAL(COtherObject)
};

class CCompoundObject : public CObject
{
   // ...Member functions
public:
   CCompoundObject();
   ~CCompoundObject();
   virtual void Serialize(CArchive &ar);

   // Implementation
protected:
   CMyObject m_myob;       // Embedded object
   COtherObject *m_pOther; // Object allocated in constructor
   CObject *m_pObDyn;      // Dynamically allocated object
   //..Other member data and implementation

   DECLARE_SERIAL(CCompoundObject)
};

 

IMPLEMENT_SERIAL(CMyObject, CObject, 1)
IMPLEMENT_SERIAL(COtherObject, CObject, 1)
IMPLEMENT_SERIAL(CCompoundObject, CObject, 1)

CCompoundObject::CCompoundObject()
{
   m_pOther = new COtherObject; // Exact type known and object already
                                //allocated.
   m_pObDyn = NULL;             // Will be allocated in another member function
                                // if needed, could be a derived class object.
}

CCompoundObject::~CCompoundObject()
{
   delete m_pOther;
}

void CCompoundObject::Serialize(CArchive &ar)
{
   CObject::Serialize(ar);  // Always call base class Serialize.
   m_myob.Serialize(ar);    // Call Serialize on embedded member.
   m_pOther->Serialize(ar); // Call Serialize on objects of known exact type.

   // Serialize dynamic members and other raw data
   if (ar.IsStoring())
   {
      ar << m_pObDyn;
      // Store other members
   }
   else
   {
      ar >> m_pObDyn; // Polymorphic reconstruction of persistent object
      //load other members
   }
}

Em resumo, se sua classe serializável definir um CObject inserido como um membro, você não deverá usar os operadores CArchive<< e >> para esse objeto, deverá chamar a função Serialize. Além disso, se sua classe serializável definir um ponteiro para um CObject (ou um objeto derivado de CObject) como um membro, mas construir esse outro objeto em um construtor próprio, você também deverá chamar Serialize.

Confira também

Serialização: serializando um objeto