我們知道CArchive類可以支持基本類型的串行化,還可以支持派生于CObject類的派生類,想要這個派生類支持可串行化,需要如下步驟即可:
(1) 從CObject類派生或者從CObject類派生的某個派生類
(2) 重寫Serialize成員函數,把類的數據成員寫入文件。
(3) 在類聲明中使用“DECLARE_SERIAL”宏
(4) 定義不帶參數的構造函數
(5) 在類的實現文件中使用“IMPLEMENT_SERIAL”宏
IMPLEMENT_SERIAL的形式如下:
IMPLEMENT_SERIAL( class_name, base_class_name, wSchema )參數: class_name 類的實際名字(不用引號括起來)。 base_class_name 基類的名字(不用引號括起來)。 wSchema 一個UINT類型的版本號。DECLARE_SERIAL的形式如下:
DECLARE_SERIAL(class_name)參數:class_name 類的實際名字
這兩個宏都是為動態的CObject派生類對象生成必要的C++代碼,包括加載數據數據使new對象等操作。
實例
下面我們將“圖形重繪和保存”這篇博文的CGraph對象串行化,使之我們能夠永久保證數據對象,其具體串行化關鍵代碼如下:
//Graph.h
//(1)派生于CObject類class CGraph:public CObject{public: //(3)聲明中使用DECLARE_SERIAL宏 DECLARE_SERIAL(CGraph) //(4)定義無參的構造函數 CGraph(void); CGraph(CPoint ptBegin, CPoint ptEnd, int DrawType); ~CGraph(void); //(2)重寫Serialize成員函數 virtual void Serialize(CArchive& ar);...PRivate: CPoint m_ptBegin; CPoint m_ptEnd; int m_DrawType;};//Graph.cpp文件代碼#include "StdAfx.h"#include "Graph.h"//(5)實現文件中使用“IMPLEMENT_SERIAL”宏IMPLEMENT_SERIAL(CGraph, CObject, 1)CGraph::CGraph(void){ m_DrawType = 0;}//Call your base class version of Serialize to make sure that the inherited portion of the object is serialized. //Insert or extract the member variables specific to your class. void CGraph::Serialize(CArchive& ar){ // call base class function first // base class is CObject in this case CObject::Serialize(ar); // now do the stuff for our specific class if (ar.IsStoring()) { ar << m_DrawType << m_ptBegin << m_ptEnd; } else { ar >> m_DrawType >> m_ptBegin >> m_ptEnd; }}我們在提取和插入類對象時,需要使用指針對象,形如:
CGraph *pGraph;ar << pGraph;//保存數據ar >> pGraph;//提取數據在提取數據時,框架會調用IMPLEMENT_SERIAL 宏,這個宏背后會幫助我們new 一個指定的對象,并將指針返回給pGraph,因此我們不要為這個指針變量分配內存空間,我們進行提?。?gt;>)和插入(<<)行為時,會發生>>或者<<運算符重載,在運行符重載過程中會有執行“pOb->Serialize(*this)”這個語句,pOb這里是CGraph對象,其中serialize是CObject 類的成員函數,它是個虛函數;CGraph類繼承于CObject,因此最終在保存對象的數據時,實際上調用的是CGraph類的serialize函數,這種調用是由框架自動完成的,從而將類對象數據寫入文件,完成永久化保存。
新聞熱點
疑難解答