首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

MFC 序列化機制全解析:CArchive、DECLARE_SERIAL、文檔視圖架構整合

     編輯:關於C++

MFC 序列化提供物件層級的檔案 I/O 抽象,深度整合於 Doc/View 架構。本文系統解析 `CArchive`、`CObject::Serialize`、`DECLARE/IMPLEMENT_SERIAL` 巨集、動態建立機制,並以幾何圖形編輯器為例示範完整實作。

序列化核心類別

  • CFile:所有檔案類別基類,提供底層 `Read`/`Write`
  • CArchive:重載 `<<`/`>>` 運算子,支援基本型別與可序列化物件
  • CObject::Serialize:虛擬函數,衍生類別實作具體讀寫邏輯

基本使用模式

讀取

CFile file; CFileException fe;
if (!file.Open(path, CFile::modeRead, &fe)) { fe.ReportError(); return; }
CArchive ar(&file, CArchive::load);
ar >> obj1 >> obj2 >> obj3;
ar.Close(); file.Close();

寫入

CFile file; CFileException fe;
if (!file.Open(path, CFile::modeWrite|CFile::modeCreate, &fe)) { ... }
CArchive ar(&file, CArchive::store);
ar << obj1 << obj2 << obj3;
ar.Flush(); ar.Close(); file.Close();

Doc/View 架構自動化流程

開啟文件 (ID_FILE_OPEN)

CDocument::OnOpenDocument(path):
  1. 建立 CFile (modeRead|shareDenyWrite)
  2. DeleteContents() 清空現有資料
  3. CArchive ar(file, load|bNoFlushOnDelete)
  4. ar.m_pDocument = this;  // 供序列化存取文檔指標
  5. Serialize(ar)  // 呼叫衍生類別實作
  6. SetModifiedFlag(FALSE)

儲存文件 (ID_FILE_SAVE/SAVEAS)

CDocument::OnSaveDocument(path):
  1. 建立 CFile (modeCreate|modeReadWrite|shareExclusive)
  2. CArchive ar(file, store|bNoFlushOnDelete)
  3. Serialize(ar)
  4. SetModifiedFlag(FALSE)

可序列化類別四要件

  1. 繼承 `CObject` (直接或間接)
  2. 實作 `virtual void Serialize(CArchive& ar)`
  3. 類別定義處使用 `DECLARE_SERIAL(ClassName)`
  4. 實作檔使用 `IMPLEMENT_SERIAL(ClassName, BaseClass, SchemaVersion)`
  5. 提供**無參數建構函數**或**全預設參數建構函數** (供 `CRuntimeClass::CreateObject`)

實戰範例:幾何圖形編輯器

基類 CPicture

class CPicture : public CObject {
    int m_nType;
    DECLARE_SERIAL(CPicture)
public:
    CPicture(int type = TYPE_UNKNOWN) : m_nType(type) {}
    virtual void Draw(CDC* pDC) = 0;
    void Serialize(CArchive& ar) {
        if (ar.IsStoring()) ar << m_nType;
        else ar >> m_nType;
    }
};
IMPLEMENT_SERIAL(CPicture, CObject, VERSIONABLE_SCHEMA | 1)

文檔類別管理圖形清單

class CPictureDoc : public CDocument {
    CTypedPtrList m_listPictures;
    // ...
    void Serialize(CArchive& ar) {
        if (ar.IsStoring()) {
            POSITION pos = m_listPictures.GetHeadPosition();
            while (pos) ar << m_listPictures.GetNext(pos);
        } else {
            RemoveAll();
            CPicture* pPic;
            while (true) {
                try { ar >> pPic; m_listPictures.AddTail(pPic); }
                catch (CException* e) { e->Delete(); break; }
            }
        }
    }
};

衍生圖形類別 (以 CLine 為例)

class CLine : public CPicture {
    CPoint m_ptStart, m_ptEnd;
    DECLARE_SERIAL(CLine)
public:
    void Serialize(CArchive& ar) {
        CPicture::Serialize(ar);  // 呼叫基類序列化
        if (ar.IsStoring()) 
            ar << m_ptStart.x << m_ptStart.y << m_ptEnd.x << m_ptEnd.y;
        else 
            ar >> m_ptStart.x >> m_ptStart.y >> m_ptEnd.x >> m_ptEnd.y;
    }
};
IMPLEMENT_SERIAL(CLine, CPicture, VERSIONABLE_SCHEMA | 2)

特殊情況處理

  • 非 CObject 類別:用 `friend operator<<`/`>>` 重載實現序列化
  • 不使用動態建立:僅需實作 `Serialize`,無需 `DECLARE/IMPLEMENT_SERIAL`
  • 版本控制:`SchemaVersion` 參數配合 `CArchive::GetObjectSchema` 實現向前/向後相容

原始碼下載

完整幾何圖形編輯器專案 (含矩形、三角形、橢圓等衍生類別) 已附於配套資源。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved