Classe Serialization: Making a Serializable
Cinque passaggi principali sono necessari rendere la classe serializzabile.Vengono elencati sotto e spiegato nelle sezioni seguenti:
Derivando una classe da CObject (o da una classe derivata da CObject).
Eseguire l'override della funzione membro Serialize.
Utilizzando la macro di DECLARE_SERIAL nella dichiarazione di classe.
Definendo un costruttore che non accetta argomenti.
Utilizzando la macro di IMPLEMENT_SERIAL nel file di implementazione per la classe.
Se si chiama direttamente Serialize anziché tra gli operatori di << e di >> di CArchive, gli ultimi tre operazioni non sono necessari per la serializzazione.
Derivando una classe da CObject
Il protocollo e la funzionalità di base di serializzazione vengono definiti nella classe di CObject .Derivando una classe da CObject (o da una classe derivata da CObject), come illustrato nella seguente dichiarazione di classe CPerson, l'accesso al protocollo di serializzazione e la funzionalità di CObject.
Eseguire l'override della funzione membro Serialize
La funzione membro di Serialize , definita nella classe di CObject , è responsabile effettivamente di serializzare i dati necessari per acquisire lo stato corrente di un oggetto.La funzione di Serialize dispone di un argomento di CArchive che utilizza per leggere e scrivere i dati dell'oggetto.L'oggetto di CArchive contiene una funzione membro, IsStoring, che indica se Serialize memorizza (scrittura di dati) o caricamento (lettura di dati).Utilizzando i risultati di IsStoring come guida, inserire i dati dell'oggetto nell'oggetto di CArchive con l'operatore di inserimento (<<) o i dati estrai con l'operatore di estrazione (>>).
Si consideri una classe derivata da CObject e di due nuovi variabili membro, tipi CString e WORD.Nel frammento della dichiarazione di classe vengono visualizzati i nuovi variabili membro e la dichiarazione della funzione membro ignorato di 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 );
};
Per eseguire l'override della funzione membro Serialize
Chiamare la versione della classe base di Serialize per assicurarsi che la parte ereditata dell'oggetto sia serializzata.
Inserire o estrarre le variabili membro specifico della classe.
Gli operatori di estrazione e di inserimento interagiscono con la classe di archiviazione per leggere e scrivere dati.Nell'esempio seguente viene illustrato come implementare Serialize per la classe di CPerson dichiarata su:
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; }
È inoltre possibile utilizzare le funzioni membro di CArchive::Write e di CArchive::Read per leggere e scrivere grandi quantità di dati non tipizzati.
Utilizzando la macro di DECLARE_SERIAL
La macro di DECLARE_SERIAL è obbligatoria nella dichiarazione di classi che supportano la serializzazione, come illustrato di seguito:
class CPerson : public CObject
{
public:
DECLARE_SERIAL( CPerson )
Definizione del costruttore senza argomenti
MFC richiede un costruttore predefinito quando si ricrea gli oggetti mentre pubblici sono deserializzati (caricato da disco).Il processo di deserializzazione compilati tutti le variabili membro con i valori necessari per ricreare l'oggetto.
Questo costruttore può essere pubblico dichiarato, protetto, o privato.Se lo possibile renderlo protetto o privato, è possibile assicurarsi che venga utilizzato solo da funzioni di serializzazione.Il costruttore deve inserire l'oggetto in uno stato che consente di stabilire se necessario.
[!NOTA]
Se non si utilizza di definire un costruttore senza argomenti in una classe che utilizza le macro di IMPLEMENT_SERIAL e di DECLARE_SERIAL , verrà visualizzato “a un nessun costruttore predefinito„ avviso del compilatore disponibile sulla riga in cui la macro di IMPLEMENT_SERIAL viene utilizzata.
Utilizzando la macro di IMPLEMENT_SERIAL nel file di implementazione
La macro di IMPLEMENT_SERIAL viene utilizzata per definire le varie funzioni necessarie quando si deriva una classe serializzabile da CObject.Si utilizza questa macro nel file di implementazione (.CPP) per la classe.I primi due argomenti alla macro è il nome della classe e il nome della classe base immediata.
Il terzo argomento a questa macro è un numero dello schema.Il numero dello schema è essenzialmente un numero di versione per gli oggetti della classe.Utilizzare maggiore o uguale a un intero 0 per il numero dello schema.(Non confondere questo numero dello schema con la terminologia del database.)
I controlli di codice di serializzazione MFC il numero dello schema durante la lettura di oggetti in memoria.Se il numero dello schema dell'oggetto su disco non corrisponde al numero dello schema della classe nella memoria, la raccolta genererà CArchiveException, non consentendo al programma di leggere una versione non corretta dell'oggetto.
Se si desidera che la funzione membro di Serialize per poter leggere le versioni, ovvero file scritti con versioni diverse dell'applicazione — è possibile utilizzare il valore VERSIONABLE_SCHEMA come argomento alla macro di IMPLEMENT_SERIAL .Per informazioni sull'utilizzo e un esempio, vedere la funzione membro di GetObjectSchema di classe CArchive.
Di seguito viene illustrato come utilizzare IMPLEMENT_SERIAL per una classe, CPerson, derivata da CObject:
IMPLEMENT_SERIAL( CPerson, CObject, 1 )
Dopo avere creato una classe serializzabile, è possibile serializzare gli oggetti della classe, come illustrato nell'articolo serializzazione: serializzare un oggetto.