Serialization: Making a Serializable 類別
若要讓類別成為可序列化需要五個主要步驟。 他們會如下所示下, 面幾節所述:
從 CObject 衍生您的類別 (或從某個類別衍生自CObject)。
覆寫的 Serialize 成員函式。
使用 DECLARE_SERIAL 巨集在類別宣告。
定義一個採用任何引數的建構函式。
在實作檔案使用 IMPLEMENT_SERIAL 巨集為您的類別。
如果您呼叫Serialize直接而非到 >> 和 << 運算子的 CArchive,最後三個步驟就不需要進行序列化。
從 CObject 衍生您的類別
基本序列化通訊協定和功能會定義在CObject類別。 藉由衍生類別從CObject (或從類別衍生自CObject),如下列的類別宣告中所示CPerson,您就能存取序列化通訊協定和功能CObject。
覆寫序列化成員函式
Serialize成員函式,定義在CObject類別,負責實際序列化的資料必須先佔領米物件的目前狀態。 Serialize函數語法包含CArchive引數,它會以讀取和寫入物件資料。 CArchive 物件有一個成員函式中, IsStoring,表示是否Serialize儲存 (寫入資料),或載入 (讀取資料)。 使用結果IsStoring作為參考,您可以插入您的物件中的資料CArchive物件,以插入運算子 (<<) 或擷取資料以引出運算子 (>>)。
請考慮一個類別衍生自CObject且有兩個新成員變數的型別CString和 WORD。 下列類別宣告片段顯示新成員變數和覆寫的宣告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 );
};
若要覆寫的 Serialize 成員函式
呼叫基底類別版本Serialize先確認物件繼承的部份會序列化。
引入或引出類別專用的成員變數。
插入和擷取運算子保存類別來讀取和寫入資料的互動。 下列範例顯示如何實作Serialize的CPerson以上的類別宣告:
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 會需要預設建構函式。 還原序列化程序會在所有成員變數中填入需要重新建立該物件的值。
這個建構函式可以宣告為公用、 受保護或私用。 如果您要保護或私用,您可以協助確定它只會用來序列化函式。 建構函式必須置於一種狀態,可以讓它在有需要時被刪除的物件。
注意事項 |
---|
假如您忘了使用的類別中定義的任何引數的建構函式DECLARE_SERIAL和IMPLEMENT_SERIAL巨集,會收到 「 沒有預設建構函式可以使用 「 編譯器警告,該行中IMPLEMENT_SERIAL使用巨集時。 |
使用 IMPLEMENT_SERIAL 巨集在實作檔案
IMPLEMENT_SERIAL巨集用來定義不同的函式需要當您衍生可序列化類別從CObject。 您可以使用此巨集在實作檔 (。CPP) 為您的類別。 為此巨集的前兩個引數是類別的名稱和其即時基底類別的名稱。
此巨集的第三個引數是一個結構描述數字。 結構描述編號是基本上是類別的物件的版本號碼。 使用結構描述編號大於或等於 0 的整數。 (請勿混淆這個結構描述編號跟資料庫術語)。
讀取到記憶體的物件時,MFC 序列化程式碼會檢查結構描述編號。 如果在磁碟上的物件的結構描述數目不符合結構描述編號在記憶體中的類別,就會擲回的文件庫CArchiveException,導致您的程式無法讀取物件的版本不正確。
如果您想要您Serialize成員函式,才能夠讀取多個版本 — 也就是撰寫應用程式的不同版本的檔案 — 您可以使用的值 VERSIONABLE_SCHEMA 做為引數至IMPLEMENT_SERIAL巨集。 使用資訊及範例,請參閱GetObjectSchema成員函式類別的CArchive。
下列範例示範如何使用IMPLEMENT_SERIAL為類別, CPerson,也就是衍生自CObject:
IMPLEMENT_SERIAL( CPerson, CObject, 1 )
一旦您有可序列化類別,您可以將序列化類別,物件的文件中所述序列化: 序列化物件。