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

MFC 序列化完整指南:從基本數據到 C++ 對象列表與自定義存儲

     編輯:關於VC++

前言

序列化是 MFC 文檔/視圖架構的核心功能之一,實現資料在記憶體與檔案之間的雙向轉換。本文通過三個漸進式範例(Memo、PHN、ARCH),系統講解基本數據序列化、CObList 管理的 C++ 對象列表序列化,以及完全自定義的 CArchive 使用技巧。

範例一:基本數據序列化 —— Memo 程式

架構要點

  • SDI + CFormView,三個編輯框對應三個 CString 變數。
  • 視圖類與文檔類各保存一份資料副本,透過 GetDocument() 同步。
  • 文檔初始化在 OnNewDocument(),視圖初始化在 OnInitialUpdate()。

核心代碼

// 文檔類
void CMemoDoc::Serialize(CArchive& ar) {
    if (ar.IsStoring())
        ar << m_strData1 << m_strData2 << m_strData3;
    else
        ar >> m_strData1 >> m_strData2 >> m_strData3;
}

選單「檔案/儲存」即自動觸發序列化,框架處理「是否儲存修改」提示。

範例二:C++ 對象列表序列化 —— PHN 程式

關鍵類別設計

class CPhone : public CObject {
    DECLARE_SERIAL(CPhone)
public:
    CString m_strName, m_strPhone;
    CPhone() {}  // 必須有無參數建構函式
    virtual void Serialize(CArchive& ar) {
        if (ar.IsStoring()) ar << m_strName << m_strPhone;
        else ar >> m_strName >> m_strPhone;
    }
};
IMPLEMENT_SERIAL(CPhone, CObject, 0)  // 版本號 0

文檔類管理列表

class CPHNDoc : public CDocument {
    CObList m_PhoneList;  // 可公開或提供 GetPhoneList()
protected:
    virtual void DeleteContents() {
        while (!m_PhoneList.IsEmpty())
            delete m_PhoneList.RemoveHead();  // 釋放記憶體
    }
    virtual void Serialize(CArchive& ar) {
        m_PhoneList.Serialize(ar);  // 一行搞定列表序列化
    }
};

前提條件:CPhone 必須繼承 CObject、擁有無參數建構函式、實作 Serialize、使用 DECLARE_SERIAL/IMPLEMENT_SERIAL。

視圖類操作列表

  • 成員:POSITION m_pos; CObList* m_pList;
  • OnInitialUpdate 取得文檔列表頭部位置,讀取第一筆資料填入介面。
  • 編輯框 EN_CHANGE 通過 UpdateData(TRUE) 回寫文檔對象並 SetModifiedFlag()。
  • 導航(上/下一筆)使用 GetPrev/GetNext 更新 m_pos 並刷新介面。
  • 新增:m_pos = m_pList->AddTail(new CPhone());刪除:delete m_pList->RemoveAt(m_pos) 並處理空列表情況。

範例三:自定義序列化 —— ARCH 程式

不依賴「檔案/儲存」選單,手動建立 CFile + CArchive 實現指定路徑存取:

// 存檔
CFile f; f.Open(_T("c:\\arc.arc"), CFile::modeCreate|CFile::modeWrite);
CArchive ar(&f, CArchive::store);
ar << m_var1 << m_var2;
ar.Close(); f.Close();

// 讀檔
CFile f; if (!f.Open(_T("c:\\arc.arc"), CFile::modeRead)) return;
CArchive ar(&f, CArchive::load);
ar >> m_var1 >> m_var2;
ar.Close(); f.Close();
UpdateData(FALSE);

適用於設定檔、快照、網路傳輸等非標準文檔流程。

常見陷阱與最佳實踐

  • 版本控制:IMPLEMENT_SERIAL 第三參數為 schema number,升級資料結構時遞增,並在 Serialize 內用 ar.GetObjectSchema() 兼容舊版。
  • 指標與多態:CObList 儲存指標時,序列化會自動保存動態類型,反序列化還原正確派生類對象。
  • 記憶體洩漏:DeleteContents 必須 delete 每個元素,否則文檔關閉/新建時洩漏。
  • 例外安全:序列化代碼建議包裹在 try/catch(CArchiveException*) 中。
  • Unicode 檔頭:二進制模式寫入 0xFF 0xFE (UTF-16LE BOM) 可避免中文亂碼。

總結

MFC 序列化機制強大且靈活:基本類型直接 <</>>,對象列表交給 CObList::Serialize,特殊需求可手動操控 CArchive。掌握 DECLARE_SERIAL/IMPLEMENT_SERIAL、無參數建構函式、DeleteContents 清理三大要素,即可在專案中穩健實現資料持久化。

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