Этот вопрос действительно нужно изучать в контексте.Если Person
s существует только в контексте Room
, то обратный указатель безопасен.Когда Room
уничтожается, тогда Person
также уничтожаются (бум!), Поэтому ничего не может пойти не так.
Но я подозреваю, что это слишком упрощенно.Объявление Room
, скорее всего, будет выглядеть примерно так:
class Room {
std::vector<std::shared_ptr<Person>> peopleInside;
};
И теперь у нас есть возможная проблема с «висящим указателем», которую вы не можете решить с помощью std::shared_pointer<Room>
в Person
потому что тогда у вас do есть круговая зависимость, и ни shared_ptr
никогда не сможет удалить объект, которым он управляет (потому что Room
содержит ссылку на Person
и наоборот, поэтому тупик).
Итак, вместо этого, объявите Person
следующим образом:
class Person {
std::weak_ptr<Room> currentRoom;
};
И инициализируйте currentRoom
из некоторого shared_ptr<Room>
, который вы сохраняете доступным, пока существует Room
.Это нарушает круговую зависимость.
Для разыменования currentRoom
, вы можете сделать:
if (auto room_I_am_currently_in = currentRoom.lock())
{
room_I_am_currently_in->OpenDoor ();
}
И если исходный shared_ptr<Room>
был уничтожен, то lock
не удастся.Блокировка будет снята, когда room_I_am_currently_in
выйдет из области видимости (на самом деле это shared_ptr<Room>
).
А чтобы переместить человека в другую комнату, просто переназначьте currentRoom
.
Подробнеео std::weak_ptr
при cpreference .