如何在C ++中序列化树结构?

时间:2011-10-23 12:47:11

标签: c++ serialization tree

我正在尝试序列化/反序列化游戏场景,以便网络发送/接收和从/向磁盘保存/加载。

我的游戏引擎使用节点和组件,因此这些是唯一需要序列化的对象。场景可能如下所示:

Root Node
  - Node
    - SpecializedComponent
    - SpecializedComponent
    - Node 
      - Node
  - Node
    - Node
    - Node
      - Node
        - Node
          - SpecializedComponent
  - Node

节点基本上是这样的:

class Node {
    map<String, Node> mChildren;
    map<String, Component> mComponents;
    uuid_t mId;
    Node* mParent;
};

SpecializedComponent基本上是这样的:

class SpecializedComponent : public Component {
    uuid_t mId;
    Node* mNode;
};

我想使用YAML或JSON作为我的文本表示。我有Qt,Boost和我想要的任何其他库,因此依赖性不是问题。实际上,节点已经是Q_OBJECTS所以我有反射。

尽管有反思,但将其正确地反序列化回C ++树结构似乎也是一个问题。

最理想的是,我想要一个优雅而有效的解决方案,将这样的结构序列化/反序列化为二进制或文本格式。

4 个答案:

答案 0 :(得分:3)

下降递归解析器通常是处理重建部分的更简单且功能更强大的选项。我可以尝试设置一些代码以具体的方式显示,在伪代码中有一些这样的东西:

 Node *parse(stream s) {
  content = new Node;
  s >> content >> nsons;
  for (int c = 0; c < nsons; ++c)
   content->addChild(parse(s));
  return content; 
 }

当然,当读取组件时,我们必须检查类型。

答案 1 :(得分:2)

我建议您使用protocol buffers library。由于您将C ++数据序列化以便在网络上发送,因此您将对此库提供的内容非常有帮助。

答案 2 :(得分:1)

序列化节点属性 序列化此节点的组件。 IE序列化子组件的数量,然后是每个组件。

为了序列化组件,您应该将An Id(int或字符串)属性化为每个组件类型(这样您就可以确定如何对hs类型的特定组件进行反序列化) 序列化子节点的数量 序列化子节点(递归调用相同的函数)

然后反序列化就是精确的镜像。 反序列化,节点属性,然后是组件数。 对于每个组件获取组件类型,根据此类型对其进行反序列化) 等等...

如果您使用Qt,QTextStream / QDataStream是最简单的选项。 二进制格式在反序列化时必须是众所周知的,因此您应该在序列化内容的生成中添加版本号或Id,以便稍后添加或更改内容。

此外,如果你必须与其他语言(如java)兼容,请注意Qt不使用与字符串类型相同的规范

答案 3 :(得分:1)

我猜你可以用Boost Serialization做到这一点。它支持所有STL容器的序列化,包括std::map