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) { // вот здесь нельзя просто взять и удалить уничтоженный объект } 
  • It may be for an object to enter a certain zombie flag, indicating that the object is no longer alive. To produce real destruction in a safe place. If I understood the problem correctly. - αλεχολυτ
  • You are trying to encode game logic with a relation between classes. It most likely will not work. Here is a series of articles by Eric Lipper about this (there is about C #, but the meaning is exactly the same). - VladD
  • @VladD, good series. Still not read, but I have a simpler task in some way - there is only one level of inheritance, almost all types interact with each other, between two objects (of a different or the same type) only one kind of interaction is possible. As for me, a classic example for double dispatch. - sba
  • @alexolut, that's exactly what I'm doing. I wanted to familiarize myself with the different options and avoid the overhead projector when searching for candidates for removal in a safe place. At the moment, just started another container where pointers to zombie-objects are placed. It turns out instead of viewing on each iteration of all objects, which are several thousand, the usually empty container is viewed. - sba
  • @sba: The idea of ​​this series is that to describe the rules, it is better not to <s> pull an owl on a globe </ s> to express it in terms of inheritance, but simply to create a separate “rulebook” essence, which you delegate all the logic decisions games. - VladD

0