Serializzazione: creazione di una classe serializzabile
Per rendere serializzabile una classe sono necessari cinque passaggi principali. Sono elencati di seguito e illustrati nelle sezioni seguenti:
Derivazione della classe da CObject (o da una classe derivata da
CObject
).Override della funzione membro Serialize.
Utilizzo della macro DECLARE_edizione Standard RIAL nella dichiarazione di classe.
Utilizzo della macro IMPLEMENT_edizione Standard RIAL nel file di implementazione per la classe.
Se si chiama Serialize
direttamente anziché tramite gli >> operatori e << di CArchive, gli ultimi tre passaggi non sono necessari per la serializzazione.
Derivazione della classe da CObject
Il protocollo e la funzionalità di serializzazione di base sono definiti nella CObject
classe . Derivando la classe da CObject
(o da una classe derivata da CObject
), come illustrato nella dichiarazione seguente della classe CPerson
, si ottiene l'accesso al protocollo di serializzazione e alla funzionalità di CObject
.
Override della funzione membro Serialize
La Serialize
funzione membro, definita nella CObject
classe , è responsabile della serializzazione effettiva dei dati necessari per acquisire lo stato corrente di un oggetto. La Serialize
funzione ha un CArchive
argomento usato per leggere e scrivere i dati dell'oggetto. L'oggetto CArchive ha una funzione membro, IsStoring
, che indica se Serialize
è in corso l'archiviazione (scrittura di dati) o il caricamento (lettura dei dati). Usando i risultati di IsStoring
come guida, inserire i dati dell'oggetto nell'oggetto CArchive
con l'operatore di inserimento (<<) o estrarre dati con l'operatore di estrazione (>>).
Si consideri una classe derivata da CObject
e con due nuove variabili membro, di tipi CString
e WORD. Il frammento di dichiarazione di classe seguente mostra le nuove variabili membro e la dichiarazione per la funzione membro sottoposta Serialize
a override:
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);
};
Per eseguire l'override della funzione membro Serialize
Chiamare la versione della classe base di per
Serialize
assicurarsi che la parte ereditata dell'oggetto sia serializzata.Inserire o estrarre le variabili membro specifiche della classe.
Gli operatori di inserimento ed estrazione interagiscono con la classe archive per leggere e scrivere i dati. L'esempio seguente illustra come implementare
Serialize
per laCPerson
classe dichiarata in precedenza: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; }
È anche possibile usare le funzioni membro CArchive::Read e CArchive::Write per leggere e scrivere grandi quantità di dati non tipizzato.
Utilizzo della macro DECLARE_edizione Standard RIAL
La macro DECLARE_edizione Standard RIAL è necessaria nella dichiarazione di classi che supporteranno la serializzazione, come illustrato di seguito:
class CPerson : public CObject
{
public:
DECLARE_SERIAL(CPerson)
Definizione di un costruttore senza argomenti
MFC richiede un costruttore predefinito quando ricrea gli oggetti perché vengono deserializzati (caricati dal disco). Il processo di deserializzazione compilerà tutte le variabili membro con i valori necessari per ricreare l'oggetto.
Questo costruttore può essere dichiarato pubblico, protetto o privato. Se lo si rende protetto o privato, è possibile assicurarsi che venga usato solo dalle funzioni di serializzazione. Il costruttore deve inserire l'oggetto in uno stato che consente di eliminarlo, se necessario.
Nota
Se si dimentica di definire un costruttore senza argomenti in una classe che utilizza le macro DECLARE_edizione Standard RIAL e IMPLEMENT_edizione Standard RIAL, verrà visualizzato un avviso del compilatore "nessun costruttore predefinito disponibile" nella riga in cui viene utilizzata la macro IMPLEMENT_edizione Standard RIAL.
Utilizzo della macro IMPLEMENT_edizione Standard RIAL nel file di implementazione
La macro IMPLEMENT_edizione Standard RIAL viene usata per definire le varie funzioni necessarie quando si deriva una classe serializzabile da CObject
. Questa macro viene usata nel file di implementazione (. CPP) per la classe. I primi due argomenti della macro sono il nome della classe e il nome della relativa classe base immediata.
Il terzo argomento di questa macro è un numero di schema. Il numero dello schema è essenzialmente un numero di versione per gli oggetti della classe . Usare un numero intero maggiore o uguale a 0 per il numero dello schema. Non confondere questo numero di schema con la terminologia del database.
Il codice di serializzazione MFC controlla il numero di schema durante la lettura degli oggetti in memoria. Se il numero di schema dell'oggetto su disco non corrisponde al numero di schema della classe in memoria, la libreria genererà , CArchiveException
impedendo al programma di leggere una versione non corretta dell'oggetto.
Se si desidera che la Serialize
funzione membro sia in grado di leggere più versioni, ovvero i file scritti con versioni diverse dell'applicazione, è possibile usare il valore VERSIONABLE_SCHEMA come argomento per la macro IMPLEMENT_edizione Standard RIAL. Per informazioni sull'utilizzo e un esempio, vedere la GetObjectSchema
funzione membro della classe CArchive
.
Nell'esempio seguente viene illustrato come usare IMPLEMENT_edizione Standard RIAL per una classe, CPerson
, derivata da CObject
:
IMPLEMENT_SERIAL(CPerson, CObject, 1)
Dopo aver creato una classe serializzabile, è possibile serializzare gli oggetti della classe, come descritto nell'articolo Serializzazione: Serializzazione di un oggetto.