用c++序列化对象

Serialize object in C++

本文关键字:对象 序列化 c++      更新时间:2023-10-16

我正在制作一款用c++编写的电子游戏,我们想让玩家保存游戏。我们发现,在这种情况下,最好的解决方案是将其中一个对象(称为game,其中包含地图,玩家等)的状态保存在文件中。

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

感谢

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

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

可以使用google协议缓冲区吗?它是另一个序列化库。如果没有,有几种方法可以让你自己滚。您还需要考虑是使用二进制格式还是人类可读的格式。对于二进制,您可以在类中做一些简单的事情,例如对输入或输出流进行序列化和反序列化方法。

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等逐行格式,比如
Name = Bob
等级= 99

MP = 109

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

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

我总是对这样的约束感到困惑。Boost就在那里,它可以工作,只需要几个小时就可以添加到项目中,然后很快解决问题——但是要花几周的时间来重新实现一个锯齿状的轮子。

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

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

基本思想很简单,您有一个类似于carchive的类来管理序列化,拥有一个数据流,并为基本类型提供I/O。通常使用一个普通函数的重载集加上一些特殊的变体。

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

最难的部分是处理指针,尤其是共享指针——运气好的话,你可以避开它。

存储格式是任意的,你甚至可以在没有人注意到的情况下在存档管理器中更改它。除非您想要在内容旁边使用标记的类xml存储,否则您必须在接口中对此进行规划。

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

然后放弃模式处理,因为几周后你的类会改变,人们仍然想要加载昨天的文件。

您确定要避免使用boost或其他库存解决方案吗?