Disons que mon jeu a un monstre qui peut exploser kamikaze sur le joueur. Choisissons un nom pour ce monstre au hasard: un Creeper. Ainsi, la Creeper
classe a une méthode qui ressemble à ceci:
void Creeper::kamikaze() {
EventSystem::postEvent(ENTITY_DEATH, this);
Explosion* e = new Explosion;
e->setLocation(this->location());
this->world->addEntity(e);
}
Les événements ne sont pas mis en file d'attente, ils sont envoyés immédiatement. Cela provoque la Creeper
suppression de l' objet quelque part dans l'appel à postEvent
. Quelque chose comme ça:
void World::handleEvent(int type, void* context) {
if(type == ENTITY_DEATH){
Entity* ent = dynamic_cast<Entity*>(context);
removeEntity(ent);
delete ent;
}
}
Étant donné que l' Creeper
objet est supprimé pendant que la kamikaze
méthode est toujours en cours d'exécution, il se bloque lorsqu'il essaie d'accéder this->location()
.
Une solution consiste à mettre les événements en file d'attente dans un tampon et à les envoyer ultérieurement. Est-ce la solution courante dans les jeux C ++? Cela ressemble à un peu de piratage, mais cela pourrait être dû à mon expérience avec d'autres langues avec différentes pratiques de gestion de la mémoire.
En C ++, existe-t-il une meilleure solution générale à ce problème lorsqu'un objet se supprime accidentellement de l'intérieur de l'une de ses méthodes?
autorelease
Objective-C, où les suppressions sont suspendues jusqu'à "juste un peu".