Compartir a través de


Almacenar y cargar CObjects a través de un archivo

Almacenar y cargar CObjects a través de un archivo requiere una atención especial. En ciertos casos, debe llamar a la función Serialize del objeto, en la que el objeto CArchive es un parámetro de la llamada a Serialize, en contraposición con el uso del operador << o >> del objeto CArchive. El hecho importante que hay que tener en cuenta es que el operador >> del objeto CArchive operador construye el objeto CObject en memoria en función de la información de CRuntimeClass que el archivo de almacenamiento escribe previamente en el archivo.

Por lo tanto, usar los operadores << y >> del objeto CArchive, en vez de llamar a Serialize, depende de si necesita que el archivo de carga reconstruya dinámicamente el objeto en función de la información de CRuntimeClass que se almacenó previamente. Use la función Serialize en estos casos:

  • Cuando deserializa el objeto, conoce la clase exacta del objeto de antemano.

  • Cuando deserializa el objeto, ya le tiene asignada memoria.

Precaución

Si carga el objeto mediante la función Serialize, también debe almacenarlo mediante la función Serialize. No lo almacene con el operador << de CArchive y luego cargue con la función Serialize, ni lo almacene con la función Serialize y luego cargue con el operador CArchive >>.

En el ejemplo siguiente, se muestran los 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
   }
}

En resumen, si la clase serializable define un objeto CObject como miembro, no debe usar los operadores << y >> de CArchive para dicho objeto, sino que debe llamar a la función Serialize. Además, si la clase serializable define un puntero a un CObject (o un objeto derivado de CObject) como miembro, pero construye este otro objeto en su propio constructor, también se debe llamar a Serialize.

Consulte también

Serialización: Serializar un objeto