首頁 > 軟體

基於MFC實現類的序列化詳解

2022-07-09 14:01:15

序列化是將程式中的物件以一種二進位制格式儲存到儲存裝置中(例如文字/資料庫等),以實現“永生”或隨意“流動”

首先定義一個要序列化的類people,其屬性有age、weight、height。

#pragma once
 
 
class people {
public:
    int age;
    int weight;
    int height;
};

定義好後將該類新增到  專案名view.h  的類中,作為其屬性,並且是指標型別

將需要存取的類實現序列化 

1.序列化的類必須從CObject派生,或是從CObject的派生類派生

#pragma once
//匯入#include<afx.h>標頭檔案,使類能繼承CObject
#include<afx.h>
 
 
class people :public CObject {
 
public:
    int age;
    int weight;
    int height;
};

2.為該類定義一個不帶引數的建構函式

3.在類宣告中使用DECLARE_SERIAL(類名)宏

#pragma once
#include<afx.h>
 
 
class people :public CObject {
public:
    DECLARE_SERIAL(people);
    people();
public:
    int age;
    int weight;
    int height;
};

4.在類的實現中新增IMPLEMENT_SERIAL(類名,父類別名,版本號)宏 

#include "pch.h"
#include "people.h"
 
//第一個引數是類的名字,第二個引數是父類別名字,第三個引數是版本號(一般版本號從1開始)
IMPLEMENT_SERIAL(people, CObject, 1);
 
people::people()
{
}

5.在類的實現中,通過類嚮導新增Serialize虛擬函式(也可也手寫)

MFC提供了CArchive類可以將物件資料儲存到永久裝置,比如磁碟檔案。當應用程式重新啟動後,CArchive類可以幫助我們從磁碟檔案讀取這些資料,然後在記憶體中重新構建對應的物件;這樣就使得我們的物件資料永久存在,該過程稱之為序列化(或者序列化)。 

void people::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {    // storing code
    }
    else
    {    // loading code
    }
}

CArchive類過載了輸入輸出運運算元,在存取時就是利用運運算元過載

void people::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {    // storing code
        //存資料
        ar << age << weight << height;
    }
    else
    {    // loading code
        //讀資料
        ar >> age >> weight >> height;
    }
}

如果說類的屬性中有自定義型別的陣列,比如下面這種,其中CPoint是MFC型別物件

#pragma once
#include<afx.h>
 
 
class people :public CObject {
public:
    CArray<CPoint>m_point;
};

那麼在 Serialize設定存取時可以安這樣

void people::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {    // storing code
        //存資料
        ar << age << weight << height;
    }
    else
    {    // loading code
        //讀資料
        ar >> age >> weight >> height;
    }
    /*直接使用陣列呼叫該方法,因為陣列已經實現了這個方法,陣列存放的元素是CPoint,CPoint
      本省也是支援序列化*/
    m_point.Serialize(ar);
}

在程式啟動時載入序列化

在Doc.cpp檔案中找到序列化介面函數

void Cdraw3Doc::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        // TODO: 在此新增儲存程式碼
    }
    else
    {
        // TODO: 在此新增載入程式碼
    }
}

從view類裡拿到要序列化的資料people*

void Cdraw3Doc::Serialize(CArchive& ar)
{
    //取出第一個view在連結串列中的位置
    POSITION pos = GetFirstViewPosition();
    //通過位置獲得該view 
    Cdraw3View* pView = (Cdraw3View* )GetNextView(pos);
    if (ar.IsStoring())
    {
        //存資料
        ar << pView->human;
    }
    else
    {
        //取資料
        ar >> pView->human;
    }
}

這樣我們每次儲存時資料就可以以二進位制序列化儲存,每次開啟時又可以開啟上次儲存的內容  

如果people*是一個陣列的話,例如這樣

那麼我們在用序列化存取時就要先存取陣列長度,再回圈存取陣列的內容 

void Cdraw3Doc::Serialize(CArchive& ar)
{
    //取出第一個view在連結串列中的位置
    POSITION pos = GetFirstViewPosition();
    //通過位置獲得該view 
    Cdraw3View* pView = (Cdraw3View* )GetNextView(pos);
    //獲得陣列長度
    int cnt = pView->human.GetSize();
    if (ar.IsStoring())
    {
        //存資料
        ar << cnt;
        for (int i = 0; i < cnt; i++) {
            //迴圈儲存陣列
            ar << pView->human.GetAt(i);
        }
    }
    else
    {
        //取長度
        ar >> cnt;
        for (int i = 0; i < cnt; ++i) {
            //依次取資料,加入到陣列中
            people* p;
            ar >> p;
            pView->human.Add(p);
        }
        
    }
}

到此這篇關於基於MFC實現類的序列化詳解的文章就介紹到這了,更多相關MFC類的序列化內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com