Partilhar via


Serialização: Criando uma classe serializável

Cinco etapas principais são necessárias para tornar uma classe serializável. Eles estão listados abaixo e explicados nas seguintes seções:

  1. Derivando sua classe de CObject (ou de alguma classe derivada de CObject).

  2. Sobrescrever a função de membro Serialize.

  3. Usando a macro DECLARE_SERIAL na declaração de classe.

  4. Definir um construtor que não usa argumentos.

  5. Usando a macro IMPLEMENT_SERIAL no arquivo de implementação para sua classe.

Se chamar Serialize diretamente, em vez de através dos operadores >> e << do CArchive, as três últimas etapas não serão necessárias para a serialização.

Derivando sua classe do CObject

O protocolo de serialização básico e a CObject funcionalidade são definidos na classe. Ao derivar a sua classe de CObject (ou de uma classe derivada de CObject), conforme mostrado na declaração de classe CPerson a seguir, obtém acesso ao protocolo de serialização e à funcionalidade do CObject.

Sobrescrevendo a função membro Serializar

A Serialize função membro, que é definida na CObject classe, é responsável por realmente serializar os dados necessários para capturar o estado atual de um objeto. A Serialize função tem um CArchive argumento que usa para ler e gravar os dados do objeto. O objeto CArchive tem uma função member, IsStoring, que indica se Serialize está armazenando (gravando dados) ou carregando (lendo dados). Usando os resultados de IsStoring como guia, você insere os dados do seu objeto no objeto CArchive com o operador de inserção (<<) ou extrai dados com o operador de extração (>>).

Considere uma classe que é derivada de CObject e tem duas novas variáveis-membro, de tipos CString e WORD. O fragmento de declaração de classe a seguir mostra as novas variáveis de membro e a declaração para a função de membro substituído 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);
};

Para sobrescrever a função membro Serialize

  1. Chame sua versão de classe base de Serialize para certificar-se de que a parte herdada do objeto é serializada.

  2. Insira ou extraia as variáveis de membro específicas da sua classe.

    Os operadores de inserção e extração interagem com a classe archive para ler e gravar os dados. O exemplo a seguir mostra como implementar Serialize para a classe declarada CPerson acima:

    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;
    }
    

Você também pode usar as funções de membro CArchive::Read e CArchive::Write para ler e gravar grandes quantidades de dados não tipados.

Usando a macro DECLARE_SERIAL

A macro DECLARE_SERIAL é necessária na declaração de classes que darão suporte à serialização, conforme mostrado aqui:

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

Definindo um construtor sem argumentos

MFC requer um construtor padrão quando recria os seus objetos ao serem desserializados (carregados do disco). O processo de desserialização preencherá todas as variáveis membro com os valores necessários para recriar o objeto.

Este construtor pode ser declarado público, protegido ou privado. Se você torná-lo protegido ou privado, você ajuda a garantir que ele só será usado pelas funções de serialização. O construtor deve colocar o objeto em um estado que permita que ele seja excluído, se necessário.

Observação

Se você esquecer de definir um construtor sem argumentos em uma classe que usa as macros DECLARE_SERIAL e IMPLEMENT_SERIAL, você receberá um aviso de compilador "nenhum construtor padrão disponível" na linha onde a macro IMPLEMENT_SERIAL é usada.

Usando a macro IMPLEMENT_SERIAL no arquivo de implementação

A macro IMPLEMENT_SERIAL é usada para definir as várias funções necessárias quando você deriva uma classe serializável de CObject. Use essa macro no arquivo de implementação (. CPP) para a sua turma. Os dois primeiros argumentos para a macro são o nome da classe e o nome de sua classe base imediata.

O terceiro argumento para esta macro é um número de esquema. O número do esquema é essencialmente um número de versão para objetos da classe. Use um inteiro maior ou igual a 0 para o número do esquema. (Não confunda esse número de esquema com a terminologia do banco de dados.)

O código de serialização MFC verifica o número do esquema ao ler objetos na memória. Se o número do esquema do objeto no disco não corresponder ao número do esquema da classe na memória, a biblioteca lançará um CArchiveException, impedindo que o programa leia uma versão incorreta do objeto.

Se você quiser que sua Serialize função de membro seja capaz de ler várias versões — ou seja, arquivos escritos com versões diferentes do aplicativo — você pode usar o valor VERSIONABLE_SCHEMA como um argumento para a macro IMPLEMENT_SERIAL. Para obter informações de uso e um exemplo, consulte a GetObjectSchema função de membro da classe CArchive.

O exemplo a seguir mostra como usar IMPLEMENT_SERIAL para uma classe, CPerson, que é derivada de CObject:

IMPLEMENT_SERIAL(CPerson, CObject, 1)

Depois de ter uma classe serializável, você pode serializar objetos da classe, conforme discutido no artigo Serialização: serializando um objeto.

Ver também

Serialização