It is necessary to implement the interaction between game entities. Double dispatch is selected as the reference point. Each class inherited from the base Cell class delegates interaction processing to the Room class.
// file : entity/Avatar.hpp #ifndef ENTITY_AVATAR_HPP #define ENTITY_AVATAR_HPP #include "Cell.hpp" class Avatar : public Cell { public: Avatar(Room& room); void interact(Cell& cell) override; void interact(Avatar& avatar) override; void interact(Food& food) override; }; #endif /* ENTITY_AVATAR_HPP */ // file : entity/Avatar.cpp void Avatar::interact(Cell& cell) { cell.interact(*this); } void Avatar::interact(Avatar& avatar) { room.interact(*this, avatar); } void Avatar::interact(Food& food) { room.interact(*this, food); }
Everything is perfect as long as the interaction does not imply the destruction of one or both of the interacting objects. Tell me how, if necessary, correctly organize the removal of one or both objects. In this case, the problem arises because all the objects that are supposed to interact with simulatedCell are first searched and stored in a container, after which at each iteration both the simulatedCell and any of the objects found for interaction can be destroyed.
void Room::interact() { for (Cell* simulatedCell: m_simulatedCells) { const auto& cells = m_gridmap.query(*simulatedCell); for (Cell* cell : cells) { cell->interact(*simulatedCell); } } } void Room::interact(Avatar& avatar1, Avatar& avatar2) { // вот здесь нельзя просто взять и удалить уничтоженный объект }
zombie
flag, indicating that the object is no longer alive. To produce real destruction in a safe place. If I understood the problem correctly. - αλεχολυτ