2

I'm developing a game for a course at my school. One of the assignments is to enable saving the game to a file and later load the game from the same file.

The problem I'm having are pointers. I'm not allocating anything on the stack (due to ownership of an item for example) so all the classes have pointers to whatever they want a reference to.

While this is quite easy to solve (assign an ID to each object and store that id instead of the pointer) the real problem comes with multiple inheritance.

Let's take the class Actor for example. It looks like this: class Actor : public Object, public ItemOwner where Object is a Obj-C-style base class which has a retain count and release, retain and autorelease methods. ItemOwner is simply an Interface which has some methods such as virtual bool add(Item *item) = 0;, virtual void remove(Item *item) = 0; and virtual bool transfer_ownership(Item *item, ItemOwner *new_owner) = 0;

Now the real question comes, which class(es?) should have ID's. And Item has a pointer to an ItemOwner while a Room has a pointer to an Actor. The actor should only be saved once.

I've thought about assigning ID's to each superclass (Object, ItemOwner, etc) but if I have a pointer to an Actor will that actor always have the same adress as the Object it contains (Actor *foo = new Actor(); foo == (Object *)foo)? If not every single class in the game will need to have an ID.

Any thoughts or suggestions would be greatly appreciated.

Derrick Turk
  • 4,246
  • 1
  • 27
  • 27
Nicklas Ansman
  • 121
  • 3
  • 10

3 Answers3

3

By using UIDs, you create a mapping:

serialized_object -> UID -> deserialized_object.

Why bothering? You already have UIDs, and these are pointers to objects. By using this mapping:

&serialized_object -> &deserialized_object

you drop a level of indirection, UIDs as created automatically, and all you have to do is to deduce this mapping in deserealization process.

The simpliest way is to serialize the objects with all the pointers as is, and to store together with each object its address. This will also help you check if an object was serialized alraedy.

While serialization would be simple, deserialization will have its tricks. You'll have to be carefull to update each old pointer (remember? they contained adresses that are no more valid) with the correct object address.

ruslik
  • 14,714
  • 1
  • 39
  • 40
  • This approach seems the simplest ATM. I've created a super-super-class called Serializable which prints the objects address and when reading I will later replace all points with the updated adresses. – Nicklas Ansman Dec 03 '10 at 12:46
  • Well, using boost could be easier and safer. But considering it's for school, it's much better to implement your own framework for that. – ruslik Dec 03 '10 at 12:59
  • This approach seems to work well, my initial tests looks quite promising. – Nicklas Ansman Dec 03 '10 at 13:46
1

One option is to define a class who's purpose in life is to hold an ID, and make it a virtual base class of every class you intend to save to disk.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • This is sort of what I'm doing now, I've got a class, Serializable, who's job it is to write the class's this pointer and read the old and make the connection to the new version – Nicklas Ansman Dec 04 '10 at 12:46
0

I would put a single per object instance, for the actor, its ID should be the same for the Object and ItemOwner, because they are all the same instance.

Also, instead of using pointers you can think about using handlers, like described here: http://gamesfromwithin.com/managing-data-relationships

bcsanches
  • 2,362
  • 21
  • 32