Giả sử trò chơi của tôi có một con quái vật có thể phát nổ trên người chơi. Hãy chọn một tên cho quái vật này một cách ngẫu nhiên: một cây leo. Vì vậy, Creeper
lớp có một phương thức trông giống như thế này:
void Creeper::kamikaze() {
EventSystem::postEvent(ENTITY_DEATH, this);
Explosion* e = new Explosion;
e->setLocation(this->location());
this->world->addEntity(e);
}
Các sự kiện không được xếp hàng, chúng được gửi đi ngay lập tức. Điều này làm cho Creeper
đối tượng bị xóa ở đâu đó bên trong cuộc gọi đến postEvent
. Một cái gì đó như thế này:
void World::handleEvent(int type, void* context) {
if(type == ENTITY_DEATH){
Entity* ent = dynamic_cast<Entity*>(context);
removeEntity(ent);
delete ent;
}
}
Bởi vì Creeper
đối tượng bị xóa trong khi kamikaze
phương thức vẫn đang chạy, nó sẽ bị sập khi nó cố truy cập this->location()
.
Một giải pháp là xếp hàng các sự kiện vào một bộ đệm và gửi chúng sau. Đó có phải là giải pháp phổ biến trong các trò chơi C ++? Cảm giác giống như một chút hack, nhưng điều đó có thể là do kinh nghiệm của tôi với các ngôn ngữ khác với các hoạt động quản lý bộ nhớ khác nhau.
Trong C ++, có một giải pháp chung tốt hơn cho vấn đề này khi một đối tượng vô tình xóa chính nó từ bên trong một trong các phương thức của nó?
autorelease
trong Objective-C, trong đó việc xóa được thực hiện cho đến khi "chỉ một chút".