在我的游戏中,我创建了一个名为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;
};
GameState中的添加和删除功能只需将参数 e 分别添加到added
和removed
集。在主循环(GameState中的其他位置)中,我在处理之前将元素从added
移动到entities
,在处理之后,我从removed
中删除entities
中的元素。这可确保在迭代期间不会修改entities
。
添加/删除功能非常简单:
void GameState::Add(Entity* e)
{
added.insert(e);
}
void GameState::Remove(Entity* e)
{
removed.insert(e);
}
每个派生的实体都在其构造函数中传递一个指向GameState的指针,它保持为game
。因此从理论上来说,从Step函数我应该可以使用像game->Remove(this);
之类的简单调用来添加和删除实体,但我得到了段错误。经过一夜的谷歌搜索,没有任何结果,我能够通过实施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 ...我感到严重的感觉我错过了一些非常基本的东西,并且引起了所有这些令人头疼的问题。谁能给我建议?
答案 0 :(得分:1)
为什么
Add(new Explosion(16,16,this))
可以在GameState
中工作,但是game->Add(new Explosion(16,16,game))
在我的对象中不起作用?
如果是这种情况,则唯一可能的解释是Entity
的{{1}}成员实际上并未指向game
。在使用之前检查它是否正确设置并验证。
这与GameState
无关。问题是您正在使用std::set
,它是您通过损坏的指针访问的类的一部分。