【问题标题】:Saving pointers to file in C++在 C++ 中保存指向文件的指针
【发布时间】:2010-12-03 11:50:39
【问题描述】:

我正在为学校的一门课程开发一款游戏。其中一项任务是允许将游戏保存到文件中,然后从同一文件中加载游戏。

我遇到的问题是指针。我没有在堆栈上分配任何东西(例如,由于项目的所有权),所以所有类都有指向它们想要引用的任何内容的指针。

虽然这很容易解决(为每个对象分配一个 ID 并存储该 ID 而不是指针),但真正的问题来自多重继承。

我们以Actor类为例。它看起来像这样:class Actor : public Object, public ItemOwner 其中Object 是一个 Obj-C 风格的基类,它具有保留计数和释放、保留和自动释放方法。 ItemOwner 只是一个接口,它有一些方法,例如virtual bool add(Item *item) = 0;virtual void remove(Item *item) = 0;virtual bool transfer_ownership(Item *item, ItemOwner *new_owner) = 0;

现在真正的问题来了,哪个类应该有 ID。 Item 有一个指向 ItemOwner 的指针,而 Room 有一个指向 Actor 的指针。 演员只能保存一次。

我考虑过为每个超类(Object、ItemOwner 等)分配 ID,但如果我有一个指向 Actor 的指针,那么该 Actor 是否总是与它包含的 Object 具有相同的地址 (Actor *foo = new Actor(); foo == (Object *)foo)?如果不是游戏中的每个班级都需要有一个 ID。

任何想法或建议将不胜感激。

【问题讨论】:

  • 这里似乎不需要多重继承。 ItemOwner 不也继承 Object 吗?
  • 好吧,不是真的,因为如果我调用 Actor::release() 它将被删除两次,而 ItemOwner 只是一个接口
  • 如果可以的话,使用 boost 序列化。
  • @Nicklas:查看 s11n (s11n.net/s11n),据我所知,它执行深度序列化并自然处理对象的循环图。

标签: c++ serialization swizzling


【解决方案1】:

通过使用 UID,您可以创建一个映射:

serialized_object -> UID -> deserialized_object.

为什么要打扰?您已经有了 UID,它们是指向对象的指针。通过使用此映射:

&serialized_object -> &deserialized_object

您删除了一个间接级别,UID 是自动创建的,您所要做的就是在去现实化过程中推导出此映射。

最简单的方法是按原样序列化带有所有指针的对象,并将其地址与每个对象一起存储。这也将帮助您检查对象是否已经序列化。

虽然序列化很简单,但反序列化也有其技巧。您必须小心地使用正确的对象地址更新每个旧指针(记住吗?它们包含不再有效的地址)。

【讨论】:

  • 这种方法似乎是最简单的ATM。我创建了一个名为 Serializable 的超类,它打印对象地址,然后在阅读时将所有点替换为更新的地址。
  • 嗯,使用 boost 可能更容易、更安全。但考虑到它是针对学校的,最好实现自己的框架。
  • 这种方法似乎效果很好,我的初步测试看起来很有希望。
【解决方案2】:

一种选择是定义一个类,该类在生活中的目的是持有一个 ID,并使其成为您打算保存到磁盘的每个类的虚拟基类。

【讨论】:

  • 这就是我现在正在做的事情,我有一个类,Serializable,它的工作是编写类的 this 指针并读取旧版本并连接到新版本
【解决方案3】:

我会为每个对象放置一个实例,对于演员,它的 ID 对于 Object 和 ItemOwner 应该是相同的,因为它们都是同一个实例。

此外,您可以考虑使用处理程序,而不是使用指针,如下所述:http://gamesfromwithin.com/managing-data-relationships

【讨论】:

    猜你喜欢
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 2011-04-24
    • 2022-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    相关资源
    最近更新 更多