Serialisierung: Erstellen einer serialisierbaren Klasse

Es sind fünf Standard Schritte erforderlich, um eine Klasse serialisierbar zu machen. Sie werden unten aufgeführt und in den folgenden Abschnitten erläutert:

  1. Ableiten der Klasse von CObject (oder von einer klasse abgeleitet von CObject).

  2. Überschreiben der Memberfunktion serialisieren.

  3. Verwenden des DECLARE_SERIAL Makros in der Klassendeklaration.

  4. Definieren eines Konstruktors, der keine Argumente akzeptiert.

  5. Verwenden des IMPLEMENT_SERIAL-Makros in der Implementierungsdatei für Ihre Klasse.

Wenn Sie direkt und nicht über die >> Operatoren << von CArchive aufrufenSerialize, sind die letzten drei Schritte nicht für die Serialisierung erforderlich.

Ableiten der Klasse von CObject

Das grundlegende Serialisierungsprotokoll und die Funktionalität werden in der CObject Klasse definiert. Durch die Ableitung Ihrer Klasse von CObject (oder von einer von ) abgeleiteten CObjectKlasse , wie in der folgenden Deklaration der Klasse CPersongezeigt , erhalten Sie Zugriff auf das Serialisierungsprotokoll und die Funktionalität von CObject.

Überschreiben der Memberfunktion "Serialisieren"

Die Serialize Elementfunktion, die in der CObject Klasse definiert ist, ist dafür verantwortlich, die zum Erfassen des aktuellen Zustands eines Objekts erforderlichen Daten tatsächlich zu serialisieren. Die Serialize Funktion weist ein CArchive Argument auf, das zum Lesen und Schreiben der Objektdaten verwendet wird. Das CArchive-Objekt verfügt über eine Memberfunktion, die angibt, IsStoringob Serialize (Daten schreiben) oder geladen werden (Lesedaten). Wenn Sie die Ergebnisse IsStoring als Anleitung verwenden, fügen Sie entweder die Daten Des Objekts mit dem Einfügeoperator (<<) in das CArchive Objekt ein, oder extrahieren Sie Daten mit dem Extraktionsoperator (>>).

Berücksichtigen Sie eine Klasse, die von CObject zwei neuen Membervariablen abgeleitet ist, von Typen CString und WORD. Das folgende Klassendeklarationsfragment zeigt die neuen Membervariablen und die Deklaration für die überschriebene Serialize Memberfunktion:

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

So überschreiben Sie die Elementfunktion serialisieren

  1. Rufen Sie die Basisklassenversion auf Serialize , um sicherzustellen, dass der geerbte Teil des Objekts serialisiert ist.

  2. Fügen Sie die Elementvariablen ein, die für Ihre Klasse spezifisch sind, oder extrahieren Sie sie.

    Die Einfüge- und Extraktionsoperatoren interagieren mit der Archivklasse, um die Daten zu lesen und zu schreiben. Das folgende Beispiel zeigt, wie sie für die CPerson oben deklarierte Klasse implementiert Serialize werden:

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

Sie können auch die Funktionen "CArchive::Read " und "CArchive::Write member" verwenden, um große Mengen von nicht typisierten Daten zu lesen und zu schreiben.

Verwenden des DECLARE_SERIAL-Makros

Das DECLARE_SERIAL Makro ist in der Deklaration von Klassen erforderlich, die die Serialisierung unterstützen, wie hier gezeigt:

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

Definieren eines Konstruktors ohne Argumente

MFC erfordert einen Standardkonstruktor, wenn sie Ihre Objekte neu erstellt, während sie deserialisiert werden (geladen vom Datenträger). Der Deserialisierungsprozess füllt alle Membervariablen mit den Werten aus, die zum erneuten Erstellen des Objekts erforderlich sind.

Dieser Konstruktor kann öffentlich, geschützt oder privat deklariert werden. Wenn Sie sie geschützt oder privat machen, stellen Sie sicher, dass sie nur von den Serialisierungsfunktionen verwendet wird. Der Konstruktor muss das Objekt in einen Zustand versetzen, mit dem es bei Bedarf gelöscht werden kann.

Hinweis

Wenn Sie vergessen, einen Konstruktor ohne Argumente in einer Klasse zu definieren, die die DECLARE_SERIAL und IMPLEMENT_SERIAL Makros verwendet, erhalten Sie eine Compilerwarnung "Kein Standardkonstruktor verfügbar" in der Zeile, in der das IMPLEMENT_SERIAL Makro verwendet wird.

Verwenden des IMPLEMENT_SERIAL-Makros in der Implementierungsdatei

Das IMPLEMENT_SERIAL Makro wird verwendet, um die verschiedenen Funktionen zu definieren, die erforderlich sind, wenn Sie eine serialisierbare Klasse von CObject. Sie verwenden dieses Makro in der Implementierungsdatei (. CPP) für Ihren Kurs. Die ersten beiden Argumente für das Makro sind der Name der Klasse und der Name der unmittelbaren Basisklasse.

Das dritte Argument für dieses Makro ist eine Schemanummer. Die Schemanummer ist im Wesentlichen eine Versionsnummer für Objekte der Klasse. Verwenden Sie eine ganze Zahl, die größer oder gleich 0 für die Schemanummer ist. (Verwechseln Sie diese Schemanummer nicht mit der Datenbankterminologie.)

Der MFC-Serialisierungscode überprüft die Schemanummer beim Lesen von Objekten in den Arbeitsspeicher. Wenn die Schemanummer des Objekts auf dem Datenträger nicht mit der Schemanummer der Klasse im Arbeitsspeicher übereinstimmt, löst die Bibliothek ein CArchiveException, hindert Das Programm daran, eine falsche Version des Objekts zu lesen.

Wenn Die Serialize Memberfunktion mehrere Versionen lesen soll , d. h. Dateien, die mit verschiedenen Versionen der Anwendung geschrieben wurden, können Sie den Wert VERSIONABLE_SCHEMA als Argument für das IMPLEMENT_SERIAL Makro verwenden. Verwendungsinformationen und ein Beispiel finden Sie in der GetObjectSchema Memberfunktion der Klasse CArchive.

Das folgende Beispiel zeigt, wie Sie IMPLEMENT_SERIAL für eine Klasse verwenden, CPersondie von CObject:

IMPLEMENT_SERIAL(CPerson, CObject, 1)

Sobald Sie über eine serialisierbare Klasse verfügen, können Sie Objekte der Klasse serialisieren, wie im Artikel Serialisierung: Serialisieren eines Objekts beschrieben.

Siehe auch

Serialisierung