Serialização: Fazendo uma classe serializável

Cinco principais etapas são necessárias para criar uma classe serializável.Elas estão listadas abaixo e explicadas nas seções a seguir:

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

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

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

  4. Definir um construtor sem argumentos.

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

Se você chamar Serialize diretamente em vez de por meio de >> e << Operadores de CArchive, as três últimas etapas não são necessárias para serialização.

Derivar sua classe de CObject

O protocolo de serialização básica e a funcionalidade são definidos no CObject classe.Derivando sua classe de CObject (ou de uma classe derivada de CObject), conforme mostrado na seguinte declaração de classe CPerson, obter acesso para o protocolo de serialização e a funcionalidade de CObject.

Substituindo o Serialize função de membro

O Serialize função de membro, que é definida na CObject da classe, é responsável pela serialização realmente os dados necessários para capturar o estado atual do objeto.O Serialize função possui um CArchive argumento que ele usa para ler e gravar os dados do objeto.O CArchive o objeto tem uma função de membro IsStoring, que indica se Serialize é armazenar (gravar dados) ou carregar (ler dados).Usando os resultados da IsStoring como guia, ou inserir dados do objeto de CArchive o objeto com o operador de inserção (<<) ou extrair dados com o operador de extração (>>).

Considere uma classe derivada de CObject e tem duas novas variáveis membro, tipos de CString e palavra.O fragmento de declaração de classe a seguir mostra o novo membro variáveis e a declaração de substituição Serialize função de membro:

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 substituir a função de membro Serialize

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

  2. Inserir ou extrair as variáveis de membro específicas para sua classe.

    Os operadores de inserção e extração de interagem com a classe de arquivamento para ler e gravar dados.O exemplo a seguir mostra como implementar Serialize para o CPerson classe declarada 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 o CArchive::Read e CArchive::Write funções de membro para ler e gravar grandes quantidades de dados tipados.

Usando a Macro DECLARE_SERIAL

O DECLARE_SERIAL macro é necessária a declaração de classes que oferecem suporte a serialização, conforme mostrado aqui:

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

Definir um construtor sem argumentos

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

Esse construtor pode ser declarada pública, protegida ou privada.Se você fizer protegida ou particular, ajudar Certifique-se de que ele será apenas usado por funções de serialização.O construtor deve colocar o objeto em um estado que permite que ele seja excluído se necessário.

ObservaçãoObservação

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

Usando a Macro IMPLEMENT_SERIAL no arquivo de implementação

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

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

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

Se você deseja que seu Serialize função de membro para poder ler várias versões — ou seja, os arquivos gravados com diferentes versões do aplicativo — você pode usar o valor VERSIONABLE_SCHEMA como um argumento para o IMPLEMENT_SERIAL macro.Para informações de uso e um exemplo, consulte o 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 uma classe serializável, você pode serializar objetos da classe, como discutido no artigo serialização: serializar um objeto.

Consulte também

Conceitos

Serialização no MFC