2015-11-14 98 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