В моем игровом движке есть три класса: EntityCharacter, EntityVehicle а также EntityVehicleSeat.
EntityVehicle содержит объекты сидений с указателями на экземпляры EntityCharacter. Если указатель объекта целевого символа объекта-сиденья является нулевым указателем, на этом конкретном объекте-сиденье нет символа. Экземпляры класса EntityCharacter также имеют указатели для размещения объектов, указывающие, находятся ли эти символьные объекты в некоторых транспортных средствах или нет.
Другими словами, экземпляр класса EntityCharacter имеет указатель на EntityVehicleSeat и наоборот:
EntityCharacter -> EntityVehicleSeat
EntityCharacter <- EntityVehicleSeat
Таким образом, мы можем проверить это право собственности через персонажа и транспортное средство.
Было бы просто установить указатели так, чтобы они указывали друг на друга, но есть одна проблема — если другой объект выпадает из области видимости, в конечном итоге мы получим неверный указатель на оставшийся объект.
Как изощренно представить этот вид собственности? Как другой объект может быть проинформирован о том, что другого объекта больше не существует?
Управление отношениями между объектами, в том числе двунаправленными, помогает деструкторам. Вы можете устранить проблему висящих указателей следующим образом:
~EntityCharacter() {
// Do some other cleanup...
...
if (seatPtr) {
assert(seatPtr->characterPtr == this); // That's my seat!
seatPtr->characterPtr = NULL;
}
}
~ EntityVehicleSeat() {
// Do some other cleanup...
...
if (characterPtr) {
assert(characterPtr->seatPtr == this); // That's my character!
characterPtr->seatPtr = NULL;
}
}
Одной из проблем этого подхода является параллелизм: если место и символ могут быть удалены одновременно из разных потоков, вам нужно будет синхронизировать удаления.
Других решений пока нет …