基于MFC實(shí)現(xiàn)類的序列化詳解
序列化是將程序中的對(duì)象以一種二進(jìn)制格式存儲(chǔ)到存儲(chǔ)設(shè)備中(例如文本/數(shù)據(jù)庫(kù)等),以實(shí)現(xiàn)“永生”或隨意“流動(dòng)”
首先定義一個(gè)要序列化的類people,其屬性有age、weight、height。
#pragma once class people { public: int age; int weight; int height; };
定義好后將該類添加到 項(xiàng)目名view.h 的類中,作為其屬性,并且是指針類型
將需要存取的類實(shí)現(xiàn)序列化
1.序列化的類必須從CObject派生,或是從CObject的派生類派生
#pragma once //導(dǎo)入#include<afx.h>頭文件,使類能繼承CObject #include<afx.h> class people :public CObject { public: int age; int weight; int height; };
2.為該類定義一個(gè)不帶參數(shù)的構(gòu)造函數(shù)
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.在類的實(shí)現(xiàn)中添加IMPLEMENT_SERIAL(類名,父類名,版本號(hào))宏
#include "pch.h" #include "people.h" //第一個(gè)參數(shù)是類的名字,第二個(gè)參數(shù)是父類名字,第三個(gè)參數(shù)是版本號(hào)(一般版本號(hào)從1開始) IMPLEMENT_SERIAL(people, CObject, 1); people::people() { }
5.在類的實(shí)現(xiàn)中,通過(guò)類向?qū)砑覵erialize虛函數(shù)(也可也手寫)
MFC提供了CArchive類可以將對(duì)象數(shù)據(jù)保存到永久設(shè)備,比如磁盤文件。當(dāng)應(yīng)用程序重新啟動(dòng)后,CArchive類可以幫助我們從磁盤文件讀取這些數(shù)據(jù),然后在內(nèi)存中重新構(gòu)建對(duì)應(yīng)的對(duì)象;這樣就使得我們的對(duì)象數(shù)據(jù)永久存在,該過(guò)程稱之為序列化(或者串行化)。
void people::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code } else { // loading code } }
CArchive類重載了輸入輸出運(yùn)算符,在存取時(shí)就是利用運(yùn)算符重載
void people::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code //存數(shù)據(jù) ar << age << weight << height; } else { // loading code //讀數(shù)據(jù) ar >> age >> weight >> height; } }
如果說(shuō)類的屬性中有自定義類型的數(shù)組,比如下面這種,其中CPoint是MFC類型對(duì)象
#pragma once #include<afx.h> class people :public CObject { public: CArray<CPoint>m_point; };
那么在 Serialize設(shè)置存取時(shí)可以安這樣
void people::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code //存數(shù)據(jù) ar << age << weight << height; } else { // loading code //讀數(shù)據(jù) ar >> age >> weight >> height; } /*直接使用數(shù)組調(diào)用該方法,因?yàn)閿?shù)組已經(jīng)實(shí)現(xiàn)了這個(gè)方法,數(shù)組存放的元素是CPoint,CPoint 本省也是支持序列化*/ m_point.Serialize(ar); }
在程序啟動(dòng)時(shí)加載序列化
在Doc.cpp文件中找到序列化接口函數(shù)
void Cdraw3Doc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: 在此添加存儲(chǔ)代碼 } else { // TODO: 在此添加加載代碼 } }
從view類里拿到要序列化的數(shù)據(jù)people*
void Cdraw3Doc::Serialize(CArchive& ar) { //取出第一個(gè)view在鏈表中的位置 POSITION pos = GetFirstViewPosition(); //通過(guò)位置獲得該view Cdraw3View* pView = (Cdraw3View* )GetNextView(pos); if (ar.IsStoring()) { //存數(shù)據(jù) ar << pView->human; } else { //取數(shù)據(jù) ar >> pView->human; } }
這樣我們每次保存時(shí)數(shù)據(jù)就可以以二進(jìn)制序列化保存,每次打開時(shí)又可以打開上次保存的內(nèi)容
如果people*是一個(gè)數(shù)組的話,例如這樣
那么我們?cè)谟眯蛄谢嫒r(shí)就要先存取數(shù)組長(zhǎng)度,再循環(huán)存取數(shù)組的內(nèi)容
void Cdraw3Doc::Serialize(CArchive& ar) { //取出第一個(gè)view在鏈表中的位置 POSITION pos = GetFirstViewPosition(); //通過(guò)位置獲得該view Cdraw3View* pView = (Cdraw3View* )GetNextView(pos); //獲得數(shù)組長(zhǎng)度 int cnt = pView->human.GetSize(); if (ar.IsStoring()) { //存數(shù)據(jù) ar << cnt; for (int i = 0; i < cnt; i++) { //循環(huán)存儲(chǔ)數(shù)組 ar << pView->human.GetAt(i); } } else { //取長(zhǎng)度 ar >> cnt; for (int i = 0; i < cnt; ++i) { //依次取數(shù)據(jù),加入到數(shù)組中 people* p; ar >> p; pView->human.Add(p); } } }
到此這篇關(guān)于基于MFC實(shí)現(xiàn)類的序列化詳解的文章就介紹到這了,更多相關(guān)MFC類的序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言 動(dòng)態(tài)內(nèi)存開辟常見問(wèn)題解決與分析流程
動(dòng)態(tài)內(nèi)存是相對(duì)靜態(tài)內(nèi)存而言的。所謂動(dòng)態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存2022-03-03C++數(shù)據(jù)結(jié)構(gòu)之單鏈表
這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之單鏈表,鏈表是由一個(gè)個(gè)結(jié)點(diǎn)鏈結(jié)成的。結(jié)點(diǎn)包括數(shù)據(jù)域和指針域兩部分,數(shù)據(jù)域用來(lái)存儲(chǔ)數(shù)據(jù)元素的信息,指針域用來(lái)存儲(chǔ)下一個(gè)結(jié)點(diǎn)的地址,更詳細(xì)內(nèi)容請(qǐng)需要的小伙伴參考下面文章內(nèi)容2022-01-01學(xué)生成績(jī)管理系統(tǒng)C++實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了學(xué)生成績(jī)管理系統(tǒng)C++實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12C語(yǔ)言學(xué)生成績(jī)管理系統(tǒng)設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言學(xué)生成績(jī)管理系統(tǒng)設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01

大家注意vector, list, set, map成員函數(shù)erase

C++實(shí)現(xiàn)LeetCode(237.刪除鏈表的節(jié)點(diǎn))

C語(yǔ)言?八大排序算法的過(guò)程圖解及實(shí)現(xiàn)代碼