我正在为我的学校开设一门课程。其中一项任务是将游戏保存到文件中,然后从同一文件加载游戏。
我遇到的问题是指针。我没有在堆栈上分配任何东西(例如由于项目的所有权)所以所有类都有指向他们想要引用的任何内容的指针。
虽然这很容易解决(为每个对象分配一个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;
现在真正的问题是,哪个类(es?)应该有ID。并且Item具有指向ItemOwner的指针,而Room具有指向Actor的指针。 演员应该只保存一次。
我考虑过为每个超类(Object,ItemOwner等)分配ID,但如果我有一个指向Actor的指针,那么该actor总是与它包含的对象(Actor *foo = new Actor(); foo == (Object *)foo)
具有相同的地址?如果不是游戏中的每个班级都需要一个ID。
非常感谢任何想法或建议。
答案 0 :(得分:3)
通过使用UID,您可以创建映射:
serialized_object -> UID -> deserialized_object.
为什么要打扰?您已经拥有UID,这些是指向对象的指针。通过使用此映射:
&serialized_object -> &deserialized_object
你删除了一个间接级别,UID是自动创建的,你所要做的就是在deserealization过程中推断出这个映射。
最简单的方法是按原样使用所有指针序列化对象,并将每个对象与其地址一起存储。这也可以帮助您检查对象是否已经过序列化。
虽然序列化很简单,但反序列化会有其技巧。您必须小心更新每个旧指针(记住吗?它们包含不再有效的地址)和正确的对象地址。
答案 1 :(得分:1)
一种选择是定义一个类,其目的是保存一个ID,并使其成为您要保存到磁盘的每个类的虚拟基类。
答案 2 :(得分:0)
我会为每个对象实例设置一个,对于actor,它的ID应该与Object和ItemOwner相同,因为它们都是相同的实例。
此外,您可以考虑使用处理程序,而不是使用指针,如下所述:http://gamesfromwithin.com/managing-data-relationships