Compartir por


Serialization: Making a Serializable (Clase)

Se requieren cinco pasos principales para convertir una clase en serializable. A continuación se enumeran y se explican en las secciones siguientes:

  1. Derivar la clase de CObject (o de alguna clase derivada de CObject).

  2. Invalidar la función miembro de Serialize.

  3. Usar la macro DECLARE_SERIAL en la declaración de clase.

  4. Definir un constructor que no tome ningún argumento.

  5. Usar la macro IMPLEMENT_SERIAL en el archivo de implementación de la clase.

Si llama Serialize directamente a en lugar de a través de los operadores >> y << de CArchive, los tres últimos pasos no son necesarios para la serialización.

Derivación de una clase de CObject

El protocolo de serialización básico y la funcionalidad se definen en la clase CObject. Al derivar la clase de CObject (o de una clase derivada de CObject), como se muestra en la siguiente declaración de clase CPerson, se obtiene acceso al protocolo de serialización y a la funcionalidad de CObject.

Invalidar la función miembro de Serialize

La función miembro Serialize, que se define en la clase CObject, es responsable de serializar realmente los datos necesarios para capturar el estado actual de un objeto. La función Serialize tiene un argumento CArchive que usa para leer y escribir los datos del objeto. El objeto CArchive tiene una función miembro, IsStoring, que indica si Serialize está almacenando (escribiendo datos) o cargando (leyendo datos). Con los resultados de IsStoring como guía, inserte los datos del objeto en el objeto CArchive con el operador de inserción (<<) o extraiga datos con el operador de extracción (>>).

Considere una clase que se deriva de CObject y tiene dos nuevas variables miembro, de tipos CString y WORD. El fragmento de declaración de clase siguiente muestra las nuevas variables miembro y la declaración de la función miembro invalidada Serialize :

class CPerson : public CObject
{
public:
   DECLARE_SERIAL(CPerson)
   // empty constructor is necessary
   CPerson();
   virtual ~CPerson();

   CString m_name;
   WORD   m_number;

   void Serialize(CArchive& archive);
};

Invalidar la función miembro de Serialize

  1. Llame a la versión de clase base de Serialize para asegurarse de que la parte heredada del objeto está serializada.

  2. Inserte o extraiga las variables miembro específicas de la clase.

    Los operadores de inserción y extracción interactúan con la clase de archivo para leer y escribir los datos. En el ejemplo siguiente se muestra cómo implementar Serialize para la clase CPerson declarada anteriormente:

    void CPerson::Serialize(CArchive& archive)
    {
       // call base class function first
       // base class is CObject in this case
       CObject::Serialize(archive);
    
       // now do the stuff for our specific class
       if (archive.IsStoring())
          archive << m_name << m_number;
       else
          archive >> m_name >> m_number;
    }
    

También puede usar las funciones miembro CArchive::Read y CArchive::Write para leer y escribir grandes cantidades de datos sin tipo.

Uso de la macro DECLARE_SERIAL

La macro DECLARE_SERIAL es necesaria en la declaración de clases que admitirá la serialización, como se muestra aquí:

class CPerson : public CObject
{
public:
   DECLARE_SERIAL(CPerson)

Definición de un constructor sin argumentos

MFC requiere un constructor predeterminado cuando vuelve a crear los objetos a medida que se deserializan (cargados desde el disco). El proceso de deserialización rellenará todas las variables miembro con los valores necesarios para volver a crear el objeto.

Este constructor se puede declarar público, protegido o privado. Si lo convierte en protegido o privado, le ayudará a asegurarse de que solo se usará para las funciones de serialización. El constructor debe colocar el objeto en un estado que permita eliminarlo si es necesario.

Nota:

Si olvida definir un constructor sin argumentos en una clase que use las macros de DECLARE_SERIAL y IMPLEMENT_SERIAL, recibirá una advertencia del compilador "sin constructor predeterminado disponible" en la línea donde se usa la macro IMPLEMENT_SERIAL.

Usar la macro IMPLEMENT_SERIAL en el archivo de implementación

La macro IMPLEMENT_SERIAL se usa para definir las distintas funciones necesarias al derivar una clase serializable desde CObject. Esta macro se usa en el archivo de implementación (.CPP) para su clase. Los dos primeros argumentos de la macro son el nombre de la clase y el nombre de su clase base inmediata.

El tercer argumento de esta macro es un número de esquema. El número de esquema es esencialmente un número de versión para los objetos de la clase . Use un entero mayor o igual que 0 para el número de esquema. (No confunda este número de esquema con terminología de base de datos).

El código de serialización de MFC comprueba el número de esquema al leer objetos en memoria. Si el número de esquema del objeto en disco no coincide con el número de esquema de la clase en memoria, la biblioteca iniciará un CArchiveException, lo que impedirá que el programa lea una versión incorrecta del objeto.

Si desea que la función miembro Serialize pueda leer varias versiones (es decir, archivos escritos con diferentes versiones de la aplicación), puede usar el valor VERSIONABLE_SCHEMA como argumento para la macro IMPLEMENT_SERIAL. Para obtener información de uso y un ejemplo, vea la función miembro GetObjectSchema de la clase CArchive.

En el ejemplo siguiente se muestra cómo usar IMPLEMENT_SERIAL para una clase, CPerson, que se deriva de CObject:

IMPLEMENT_SERIAL(CPerson, CObject, 1)

Una vez que tenga una clase serializable, puede serializar objetos de la clase, como se describe en el artículo Serialización: Serialización de un objeto.

Consulte también

Serialización