1

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

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

谢谢

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

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

2 回答 2

4

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

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 或类似的逐行操作:
名称 = Bob
Level = 99
HP = 201
MP = 109
...

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

class ISerializable {  
     virtual void serialize(std::ostream output) = 0;  
     virtual void deserialize(std::istream output) = 0;  
 }
于 2013-06-03T00:53:49.173 回答
2

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

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

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

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

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

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

存储格式是任意的,您甚至可以在存档管理器中更改它,而不会引起任何人的注意。除了您想要在内容旁边使用标签的类 XML 存储之外,您必须在界面中对此进行计划。

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

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

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

于 2013-06-03T00:37:15.473 回答