Delen via


Serialisatie: een serialiseerbare klasse maken

Er zijn vijf hoofdstappen vereist om een klasse serialiseerbaar te maken. Deze worden hieronder vermeld en uitgelegd in de volgende secties:

  1. Uw klasse afleiden van CObject (of van een bepaalde klasse afgeleid van CObject).

  2. De functie Serialiseren van lid overschrijven.

  3. Gebruik de DECLARE_SERIAL macro in de klassedeclaratie.

  4. Een constructor definiëren waarvoor geen argumenten nodig zijn.

  5. Gebruik de IMPLEMENT_SERIAL macro in het implementatiebestand voor uw klas.

Als u Serialize rechtstreeks aanroept in plaats van via de >> en <<-operatoren van CArchive, zijn de laatste drie stappen niet vereist voor serialisatie.

Uw klas afleiden van CObject

Het basisserialisatieprotocol en de functionaliteit worden gedefinieerd in de CObject klasse. Door uw klasse CObject af te leiden van (of van een klasse die is afgeleid van CObject), zoals wordt weergegeven in de volgende verklaring van klasse CPerson, krijgt u toegang tot het serialisatieprotocol en de functionaliteit van CObject.

De functie Lid serialiseren overschrijven

De Serialize lidfunctie, die in de CObject klasse is gedefinieerd, is verantwoordelijk voor het serialiseren van de gegevens die nodig zijn om de huidige status van een object vast te leggen. De Serialize functie heeft een CArchive argument dat wordt gebruikt om de objectgegevens te lezen en te schrijven. Het CArchive-object heeft een lidfunctie, IsStoringdie aangeeft of Serialize het opslaan (schrijven van gegevens) of het laden (lezen van gegevens) aangeeft. Met behulp van de resultaten van IsStoring als hulplijn voegt u de gegevens van uw IsStoring object in het << object met de invoegoperator (>>) of extraheert u gegevens met de extractieoperator ().

Overweeg een klasse die is afgeleid van CObject en twee nieuwe lidvariabelen heeft, van typen CString en WORD. In het volgende fragment van de klassedeclaratie worden de nieuwe lidvariabelen en de declaratie voor de overschreven Serialize lidfunctie weergegeven:

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

De functie Lid serialiseren overschrijven

  1. Roep uw basisklasseversie van Serialize aan om ervoor te zorgen dat het geërfde deel van het object wordt geserialiseerd.

  2. Voeg de lidvariabelen in of pak deze uit die specifiek zijn voor uw klasse.

    De invoeg- en extractieoperators communiceren met de archiefklasse om de gegevens te lezen en te schrijven. In het volgende voorbeeld ziet u hoe u implementeert Serialize voor de CPerson klasse die hierboven is gedeclareerd:

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

U kunt ook de functies CArchive::Read en CArchive::Write member gebruiken om grote hoeveelheden niet-getypte gegevens te lezen en schrijven.

De DECLARE_SERIAL macro gebruiken

De DECLARE_SERIAL macro is vereist in de declaratie van klassen die serialisatie ondersteunen, zoals hier wordt weergegeven:

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

Een constructor zonder argumenten definiëren

Voor MFC is een standaardconstructor vereist wanneer uw objecten opnieuw worden gemaakt wanneer ze worden gedeserialiseerd (geladen vanaf schijf). Tijdens het deserialisatieproces worden alle lidvariabelen ingevuld met de waarden die nodig zijn om het object opnieuw te maken.

Deze constructor kan openbaar, beveiligd of privé worden gedeclareerd. Als u deze beveiligd of privé maakt, zorgt u ervoor dat deze alleen wordt gebruikt door de serialisatiefuncties. De constructor moet het object in een status plaatsen waarmee het indien nodig kan worden verwijderd.

Opmerking

Als u vergeet een constructor te definiëren zonder argumenten in een klasse die gebruikmaakt van de DECLARE_SERIAL en IMPLEMENT_SERIAL macro's, krijgt u de waarschuwing 'geen standaardconstructor beschikbaar' op de regel waarop de IMPLEMENT_SERIAL macro wordt gebruikt.

De IMPLEMENT_SERIAL-macro in het implementatiebestand gebruiken

De IMPLEMENT_SERIAL macro wordt gebruikt om de verschillende functies te definiëren die nodig zijn wanneer u een serialiseerbare klasse afleiden van CObject. U gebruikt deze macro in het implementatiebestand (. CPP) voor uw klas. De eerste twee argumenten voor de macro zijn de naam van de klasse en de naam van de directe basisklasse.

Het derde argument voor deze macro is een schemanummer. Het schemanummer is in feite een versienummer voor objecten van de klasse. Gebruik een geheel getal dat groter is dan of gelijk is aan 0 voor het schemanummer. (Dit schemanummer wordt niet verward met databaseterminologie.)

De MFC-serialisatiecode controleert het schemanummer bij het lezen van objecten in het geheugen. Als het schemanummer van het object op schijf niet overeenkomt met het schemanummer van de klasse in het geheugen, genereert de bibliotheek een CArchiveException, waardoor uw programma geen onjuiste versie van het object kan lezen.

Als u wilt dat uw Serialize lidfunctie meerdere versies kan lezen, dat wil gezegd, bestanden die zijn geschreven met verschillende versies van de toepassing, kunt u de waarde VERSIONABLE_SCHEMA gebruiken als argument voor de IMPLEMENT_SERIAL macro. Zie de GetObjectSchema lidfunctie van klasse CArchivevoor gebruiksgegevens en een voorbeeld.

In het volgende voorbeeld ziet u hoe u IMPLEMENT_SERIAL gebruikt voor een klasse, CPersondie is afgeleid van CObject:

IMPLEMENT_SERIAL(CPerson, CObject, 1)

Zodra u een serialiseerbare klasse hebt, kunt u objecten van de klasse serialiseren, zoals beschreven in het artikel Serialisatie: Een object serialiseren.

Zie ook

serialisatie