Digamos que mi juego tiene un monstruo que puede explotar kamikaze en el jugador. Vamos a elegir un nombre para este monstruo al azar: un Creeper. Entonces, la Creeper
clase tiene un método que se parece a esto:
void Creeper::kamikaze() {
EventSystem::postEvent(ENTITY_DEATH, this);
Explosion* e = new Explosion;
e->setLocation(this->location());
this->world->addEntity(e);
}
Los eventos no están en cola, se envían de inmediato. Esto hace que el Creeper
objeto se elimine en algún lugar dentro de la llamada a postEvent
. Algo como esto:
void World::handleEvent(int type, void* context) {
if(type == ENTITY_DEATH){
Entity* ent = dynamic_cast<Entity*>(context);
removeEntity(ent);
delete ent;
}
}
Debido a que el Creeper
objeto se elimina mientras el kamikaze
método aún se está ejecutando, se bloqueará cuando intente acceder this->location()
.
Una solución es poner los eventos en cola en un búfer y enviarlos más tarde. ¿Es esa la solución común en los juegos de C ++? Se siente como un truco, pero eso podría deberse a mi experiencia con otros idiomas con diferentes prácticas de administración de memoria.
En C ++, ¿existe una mejor solución general para este problema en el que un objeto se elimina accidentalmente de uno de sus métodos?
autorelease
en Objective-C, donde las eliminaciones se detienen hasta por "solo un poco".