2010-12-03 2 views
2

Я разрабатываю игру для курса в моей школе. Одно из заданий - включить сохранение игры в файл, а затем загрузить игру из того же файла.Сохранение указателей на файл в C++

Проблема у меня есть указатели. Я не выделяю что-либо в стеке (из-за владения элементом, например), поэтому все классы имеют указатели на то, на что они хотят ссылаться.

Хотя это довольно легко решить (назначить идентификатор каждому объекту и сохранить этот идентификатор вместо указателя), настоящая проблема связана с множественным наследованием.

Давайте возьмем класс Актера, например. Он выглядит следующим образом: 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;

Теперь возникает вопрос, какой класс (ы) должен иметь идентификаторы. И Item имеет указатель на ItemOwner, в то время как в комнате есть указатель на актера. Актер должен быть сохранен только один раз.

Я думал о назначении идентификаторов каждому суперклассу (Object, ItemOwner и т. Д.), Но если у меня есть указатель на актер, этот актер всегда будет иметь тот же адрес, что и Object, который содержит (Actor *foo = new Actor(); foo == (Object *)foo)? Если не каждый класс в игре должен иметь идентификатор.

Любые мысли или предложения были бы весьма признательны.

+2

Это подпадает под тему http://en.wikipedia.org/wiki/Serialization. – Sabuncu 2010-12-03 11:54:22

+0

Множественное наследование кажется ненужным здесь. Разве `ItemOwner` не наследует` Object`? – jwueller 2010-12-03 11:55:36

+0

Ну, на самом деле, потому что если я вызову Actor :: release(), он будет удален дважды, а ItemOwner - это просто интерфейс. – 2010-12-03 11:58:55

ответ

3

С помощью UIDs, вы создаете отображение:

serialized_object -> UID -> deserialized_object. 

Почему беспокоит? У вас уже есть UID, и это указатели на объекты. С помощью этого отображения:

&serialized_object -> &deserialized_object 

вы уронили уровень косвенности, UIDs, как создается автоматически, и все, что вам нужно сделать, это вывести это отображение в процессе deserealization.

Самый простой способ - сериализовать объекты со всеми указателями как есть и сохранить вместе с каждым объектом его адрес. Это также поможет вам проверить, был ли объект сериализован alraedy.

Хотя сериализация была бы простой, десериализация будет иметь свои трюки. Вы должны быть осторожны, чтобы обновлять каждый старый указатель (помните, что они содержали не более достоверные адреса) с правильным адресом объекта.

1

Одним из вариантов является определение класса, целью которого является сохранение идентификатора и создание его виртуального базового класса для каждого класса, который вы собираетесь сохранить на диск.

0

Я бы поместил один экземпляр объекта для объекта, для актера его идентификатор должен быть одинаковым для Object и ItemOwner, потому что они все одинаковы.

Кроме того, вместо того, чтобы использовать указатели вы можете думать об использовании обработчиков, как описано здесь: http://gamesfromwithin.com/managing-data-relationships

Смежные вопросы