在C ++中序列化对象

时间:2013-06-03 00:16:53

标签: c++ file serialization

我正在开发一个用C ++编写的视频游戏,我们想让玩家保存游戏。我们发现在我们的情况下,最好的解决方案是在文件中保存其中一个对象(称为game,其中包含地图,玩家等)的状态。

问题:我不能使用提升。那么,最好和最简单的解决方案是什么?

由于

编辑:我可以使用其他库作为谷歌协议缓冲区。在game中有复杂的对象:

Camera              _camera; 
std::list<AObject*> _objects;
int                 size_map;

2 个答案:

答案 0 :(得分:4)

您可以使用google protocol buffers吗?这是另一个序列化库。如果没有,有几种方法可以自己动手。您还需要考虑是否要使用二进制格式或人类可读格式。对于二进制文件,您可以在类中执行一些简单的操作,例如对输入或输出流的序列化和反序列化方法。

struct MyStruct {  
    int data;  
    int more_data;  
    double even_more_data;  
    void serialize(std::ostream output) {  
        output.write((char *)&data, sizeof(data));  
        output.write((char *)&more_data, sizeof(more_data));  
        output.write((char *)&even_more_data, sizeof(even_more_data));  
    }  
    void deserialize(std::istream input) {  
        input.read((char *)&data, sizeof(data));  
        input.read((char *)&more_data, sizeof(more_data));  
        input.read((char *)&even_more_data, sizeof(even_more_data));  
    }  
}

如果你需要包含一个字符串,你需要写出大小然后写出字符串,所以当你读回来时,你知道要读多少个字符。您可以做的其他一些事情是XML,JSON,CSV或逐行的事情,例如:
姓名=鲍勃
等级= 99
HP = 201
MP = 109
......

您可能还想为可序列化对象创建一个接口:

class ISerializable {  
     virtual void serialize(std::ostream output) = 0;  
     virtual void deserialize(std::istream output) = 0;  
 }

答案 1 :(得分:2)

我总是对这样的限制感到困惑。 Boost在那里,有效,只需几个小时就可以添加到项目中,然后立即解决问题 - 而是花费数周时间重新实现锯齿状的轮子。

如果你不使用助力,你仍然可以学习它。代码本身可能会像往常一样使用宏,但界面可以提供洞察力。

如果您有MSVC,无论旧版本如何,都可以针对设计和实施来研究MFC。这个非常简单,您可以使用这些想法创建自己的变体。猜猜你可以找到更多现有的框架。

基本思想很简单,你有一个类似CArchive的类来管理序列化,拥有数据流,并为基元类型提供I / O.通常使用常见功能的过载集和一些特殊变体。

然后,通过为每个数据成员调用该函数,使所有类实现自己的加载和保存。它可能是侵入性的,或者使用重载的自由函数或专门化模板或它们的某种组合。还在某处添加对序列化集合的支持 - 不是很难,因为它只是迭代并调用序列化项目。对于智能指针。

困难的部分是处理指针,特别是共享指针 - 幸运的是,你可以回避它。

商店格式是任意的,您甚至可以在存档管理器中更改它,而无需任何人注意。除了您希望在内容旁边使用标签的类似XML的商店外,您必须在界面中为此计划。

对于多态指针,您需要更多支持,一些工厂设施和标识符。

然后放入架构处理,因为几周后你的课程会改变,人们仍然想要加载昨天的文件。

您确定要避免使用提升或其他股票解决方案吗?