次の方法で共有


シリアル化 : シリアル化可能なクラスの作成

クラスをシリアル化できるようにするには、5 つの主要な手順を実行する必要があります。 これらは次のセクションで説明されています。

  1. CObject から (または CObject から派生するクラスから) クラスを派生します。

  2. シリアル化メンバー関数をオーバーライドしています

  3. クラス宣言で、DECLARE_SERIAL macro マクロを使用します。

  4. 引数を受け取らないコンストラクターを定義します

  5. クラスの実装ファイルで IMPLEMENT_SERIAL マクロを使用します

CArchive の >> および << の演算子を使用せずに Serialize を直接呼び出す場合、最後の 3 つの手順はシリアル化には必要ありません。

CObject からのクラスの派生

基本的なシリアル化プロトコルと機能は、CObject クラスで定義されています。 クラス CPerson の次の宣言に示すように、CObject から (または CObject から派生したクラスから) クラスを派生させることにより、CObject のシリアル化プロトコルと機能にアクセスできます。

シリアル化メンバー関数をオーバーライドする

CObject クラスで定義されている Serialize メンバー関数は、オブジェクトの現在の状態をキャプチャするために必要なデータを実際にシリアル化する役割を担います。 Serialize 関数には、オブジェクト データの読み取りと書き込みに使用する CArchive 引数があります。 CArchive オブジェクトには、メンバー関数 IsStoring があり、これは Serialize が格納しているか (データの書き込み)、読み込んでいる (データの読み取り) のいずれであるかを示します。 ガイドとしての IsStoring の結果を使用して、挿入演算子 (<<) を使用して CArchive オブジェクトにオブジェクトのデータを挿入するか、抽出演算子 (>>) を使用してデータを抽出します。

CObject から派生したクラスがあり、型 CStringWORD の 2 つの新しいメンバー変数があるとします。 次のクラス宣言フラグメントは、新しいメンバー変数と、オーバーライドされた 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);
};

シリアル化メンバー関数をオーバーライドするには

  1. Serialize の基底クラスのバージョンを呼び出して、継承されたオブジェクト部分がシリアル化されるようにします。

  2. クラスに固有のメンバー変数を挿入または抽出します。

    挿入演算子と抽出演算子は アーカイブ クラスとやり取りして、データの読み取りと書き込みを行います。 次の例は、上記で宣言した CPerson クラスに Serialize を実装する方法を示しています。

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

また、 CArchive::Read および CArchive::Write メンバー関数を使用して、大量の型指定されていないデータの読み取りと書き込みを行うこともできます。

DECLARE_SERIAL マクロの使用

次に示すように、シリアル化をサポートするクラスの宣言には、DECLARE_SERIAL マクロが必要です。

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

引数を指定せずにコンストラクターを定義する

MFC では、オブジェクトが逆シリアル化される (ディスクから読み込まれる) ときに、既定のコンストラクターが必要になります。 逆シリアル化プロセスでは、オブジェクトを再作成するために必要な値がすべてのメンバー変数に入力されます。

このコンストラクターは、public、protected、または private として宣言できます。 保護またはプライベートにすると、シリアル化関数によってのみ使用されるようになります。 コンストラクターは、必要に応じてオブジェクトを削除できる状態にする必要があります。

Note

DECLARE_SERIAL と IMPLEMENT_SERIAL のマクロを使用するクラスに引数のないコンストラクターを定義し忘れた場合、IMPLEMENT_SERIAL マクロが使用されている行に "既定のコンストラクターは使用できません" というコンパイラの警告が表示されます。

実装ファイルで IMPLEMENT_SERIAL マクロを使用する

IMPLEMENT_SERIAL マクロは、CObject から シリアル化可能なクラスを派生させるときに必要なさまざまな関数を定義するために使用されます。 このマクロは、クラスの実装ファイル (.CPP) で使用します。 マクロの最初の 2 つの引数は、クラスの名前と、その直接の基底クラスの名前です。

このマクロの 3 番目の引数は、スキーマ番号です。 スキーマ番号は、本質的にはクラスのオブジェクトのバージョン番号です。 スキーマ番号には 0 以上の整数を使用してください。 (このスキーマ番号をデータベース用語と混同しないでください)。

MFC シリアル化コードは、オブジェクトをメモリに読み込むときにスキーマ番号をチェックします。 ディスク上のオブジェクトのスキーマ番号がメモリ内のクラスのスキーマ番号と一致しない場合、ライブラリは CArchiveException をスローし、プログラムが正しくないバージョンのオブジェクトを読み取ることを防ぎます。

Serialize メンバー関数が複数のバージョン (異なるバージョンのアプリケーションで記述されたファイル) を読み取ることができるようにする場合は、IMPLEMENT_SERIAL マクロの引数として VERSIONABLE_SCHEMA 値を使用できます。 使用方法と例については、「クラス CArchiveGetObjectSchema メンバー関数」を参照してください。

次の例は、CObject から派生したクラス CPerson の IMPLEMENT_SERIAL を使用する方法を示しています:

IMPLEMENT_SERIAL(CPerson, CObject, 1)

シリアル化可能なクラスを作成した後は、「シリアル化: オブジェクトのシリアル化」で説明されているように、クラスのオブジェクトをシリアル化できます。

関連項目

シリアル化