В моей игре я создал базовый класс Entity, который я храню в наборе для обработки.Все мои игровые объекты происходят из этого класса, и у меня нет проблем с добавлением производных типов указателей к набору в моей функции инициализации.
Проблема заключается в добавлении новых элементов из в функции Step()
сущности.Теперь, прежде чем я углублюсь в это, я покажу вам несколько упрощенный код:
class GameState
{
public:
GameState();
~GameState();
...
set<Entity*> entities;
void Add(Entity* e);
void Remove(Entity* e);
protected:
set<Entity*> added, removed;
};
class Entity
{
public:
Entity();
Entity(GameState* parent);
virtual ~Entity();
virtual void Step(const sf::Input& input);
...
virtual void Destroy();
protected:
GameState* game;
};
Функции Add и Remove в GameState просто добавляют аргумент e к added
и removed
комплектов соответственно.В основном цикле (где-то еще в GameState) перед обработкой я перемещаю элементы с added
на entities
, а после обработки удаляю элементы из removed
из entities
.Это гарантирует, что entities
не изменяется во время итерации.
Функции Add / Remove очень просты:
void GameState::Add(Entity* e)
{
added.insert(e);
}
void GameState::Remove(Entity* e)
{
removed.insert(e);
}
Каждому производному объекту передается указатель на GameState в его конструкторе, который он сохраняет как game
.Таким образом, теоретически из функции Step я должен иметь возможность добавлять и удалять сущности с помощью простого вызова, например game->Remove(this);
, но вместо этого я получаю ошибку сегмента.После ночи поисков в Google и ничего не придумав, я смог обойти (частично) проблему, реализовав Entity::Destroy()
следующим образом:
void Entity::Destroy()
{
game->Remove(this);
}
Итак, мой первый вопрос: почему this
работать, когда я нахожусь в базовом классе, но не в производном классе?
Еще более загадочным для меня является Add()
.Почему Add(new Explosion(16,16,this))
работает в GameState, но game->Add(new Explosion(16,16,game))
не работает внутри моего объекта?
Я запустил его через GDB, и он говорит мне:
Program received signal SIGSEGV, Segmentation fault.
At c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:482
Код, который выбрасываетошибка:
_Link_type
_M_begin()
{ return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } //this line
Итак, подведя итог, я понятия не имею, почему мои указатели нарушают STL ... и у меня возникает такое серьезное чувство, что я упускаю что-то очень простое и вызывает все эти головные боли,Кто-нибудь может дать мне совет?