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

MFC 序列化實戰(三):四類常見類別架構完整範例

     編輯:關於C語言

統一狀態碼定義

enum Status { Success, InvalidFormat, UnsupportedVersion, ReadError, WriteError };

1. 簡單類別

無基底類別、無聚合成員。步驟:簽名+版本 → 成員。

class Point {
    int m_nX, m_nY;
    static const CString m_strSignature;
    static const int m_nVersion;
public:
    int Serialize(CArchive* pArchive);
};

int Point::Serialize(CArchive* pArchive) {
    ASSERT(pArchive);
    int nVer;
    try {
        if (pArchive->IsStoring()) {
            *pArchive << m_strSignature << m_nVersion;
            *pArchive << m_nX << m_nY;
        } else {
            CString sig; *pArchive >> sig;
            if (sig != m_strSignature) return InvalidFormat;
            *pArchive >> nVer;
            if (nVer > m_nVersion) return UnsupportedVersion;
            *pArchive >> m_nX >> m_nY;
        }
    } catch (CException* e) {
        e->Delete();
        return pArchive->IsStoring() ? WriteError : ReadError;
    }
    return Success;
}

2. 衍生類別

繼承簡單類別。步驟:簽名+版本 → 基底類別 Serialize() → 自身成員。

class ColoredPoint : public Point {
    int m_nColor;
    static const CString m_strSignature;
    static const int m_nVersion;
public:
    int Serialize(CArchive* pArchive);
};

int ColoredPoint::Serialize(CArchive* pArchive) {
    ASSERT(pArchive);
    int nVer;
    try {
        if (pArchive->IsStoring()) {
            *pArchive << m_strSignature << m_nVersion;
        } else {
            CString sig; *pArchive >> sig;
            if (sig != m_strSignature) return InvalidFormat;
            *pArchive >> nVer;
            if (nVer > m_nVersion) return UnsupportedVersion;
        }
        int nStatus = Point::Serialize(pArchive); // 序列化基底
        if (nStatus != Success) return nStatus;
        if (pArchive->IsStoring()) *pArchive << m_nColor;
        else *pArchive >> m_nColor;
    } catch (CException* e) {
        e->Delete();
        return pArchive->IsStoring() ? WriteError : ReadError;
    }
    return Success;
}

3. 同質聚合類別

包含動態數量的同型別物件(如 CPtrArray 存 ColoredPoint*)。步驟:簽名+版本 → 基底(如有) → 元素計數 → 逐個元素 Serialize() → 其他成員。

class ColoredPointList {
    CPtrArray m_arrPoints;
    static const CString m_strSignature;
    static const int m_nVersion;
public:
    int Serialize(CArchive* pArchive);
};

int ColoredPointList::Serialize(CArchive* pArchive) {
    ASSERT(pArchive);
    int nVer;
    try {
        if (pArchive->IsStoring()) {
            *pArchive << m_strSignature << m_nVersion;
            int nCount = m_arrPoints.GetSize();
            *pArchive << nCount;
            for (int i = 0; i < nCount; ++i) {
                ColoredPoint* p = (ColoredPoint*)m_arrPoints[i];
                int nStatus = p->Serialize(pArchive);
                if (nStatus != Success) return nStatus;
            }
        } else {
            CString sig; *pArchive >> sig;
            if (sig != m_strSignature) return InvalidFormat;
            *pArchive >> nVer;
            if (nVer > m_nVersion) return UnsupportedVersion;
            int nCount; *pArchive >> nCount;
            for (int i = 0; i < nCount; ++i) {
                ColoredPoint* p = new ColoredPoint();
                int nStatus = p->Serialize(pArchive);
                if (nStatus != Success) { delete p; return nStatus; }
                m_arrPoints.Add(p);
            }
        }
    } catch (CException* e) {
        e->Delete();
        return pArchive->IsStoring() ? WriteError : ReadError;
    }
    return Success;
}

4. 異質聚合類別

包含不同型別物件(需多型)。序列化時需在每個元素前寫入型別標識,讀取時依標識動態建立對應物件並呼叫虛擬 Serialize()。

設計原則總結

  1. 簽名、版本永遠優先序列化。
  2. 衍生類別必須呼叫基底 Serialize()。
  3. 聚合類別序列化「計數 → 逐項」,異質聚合額外需「型別標識 → 工廠建立 → 序列化」。
  4. 統一錯誤碼、統一例外處理、釋放暫存物件記憶體。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved