2015-11-14 130 views
0

我需要序列化指向基類和派生類的向量。 Serialize函數重載兩個類,所以我做了它成功地這樣的:`C++ MFC序列化

CFile out; 
if (!out.Open(filename.c_str(), CFile::modeWrite | CFile::modeCreate)) 
    return false; 

CArchive ar(&out, CArchive::store); 
for (auto it = container_.begin(); it != container_.end(); ++it) 
{ 
    (*it)->Serialize(ar); 
} 
ar.Close(); 
out.Close(); 

因此問題是,我應該怎麼現在反序列化呢?在從CArchive中讀取對象時調用正確的構造函數沒有任何想法...

+1

根本不調用構造函數。您只需使用CArchive類的'operator >>',並獲取指向完全構造的對象的指針(參見[通過存檔存儲和加載CObjects](https://msdn.microsoft.com/zh-cn/ /library/3bfsbt0t.aspx))。但是,存儲矢量的方式使其無法恢復:您錯過了元素的數量,因此在重新讀入檔案時,您不知道何時停止閱讀其他元素。你必須先寫數。使用MFC容器類自動執行所有這些。 – IInspectable

回答

1

您首先需要保存容器中元素的數量(使用ar.WriteCount)。然後(因爲你的容器有多個類型)爲你序列化的每個元素,你需要包含額外的數據來告訴你這個元素的類型是什麼。這可能只是一個額外的字符(0 =基類,1 =第一個派生類),另一個計數類型編號(使用WriteCount編寫)或類型名稱等更詳細的內容。

要讀取它,請閱讀元素數(使用ar.ReadCount),然後對於讀入的每個元素,讀取類型字符,計數或其他值,分配一個新類型的元素,反序列化爲新分配的元素元素,最後將分配的元素存儲到您正在反序列化的容器中。

爲了從MFC容器轉換到STL,我需要做很多年前類似的事情,MFC容器使用的序列化實現(在<afxtempl.h>中)非常有用。

+0

非常感謝,但是由於它是用MFC文檔編寫的,因此serialize會將運行時類型信息存儲在數據(CRuntimeClass或類似的東西)中。我們可以使用它而不是寫入額外的類型信息嗎? – Uroboros

+1

沒有'CArchive :: WriteCount'或'CArchive :: ReadCount'。存儲類型信息也不需要(MFC序列化基礎架構已經爲您準備)。你只需調用'ar >> pObj',框架就會返回一個指向完全構造對象的指針。即使您將一個指向基類(通常爲'CObject')的指針傳遞給'operator >>',該對象的類型也是正確的。 – IInspectable

+0

@IInspectable它們沒有記錄(不是從afx.h中的類定義中可以看出的),而是'CList :: Serialize'使用的'CArchive'的公共成員和其他相關函數。自從我使用CArchive並忘記了課程詳細信息以來,已經有一段時間了。 – 1201ProgramAlarm