在我的游戏中,我创建了一个名为 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 中的 Add 和 Remove 函数只是将参数 e 分别添加到 added
和 removed
集合中。在主循环中(在 GameState 的其他地方),我在处理之前将元素从 added
移动到 entities
,在处理之后我从 removed
中移除元素实体
。这可确保 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...而且我有一种严重的感觉,我错过了一些非常基本的东西,它导致了所有这些令人头疼的事情。谁能给我建议?
最佳答案
Why does
Add(new Explosion(16,16,this))
work inGameState
butgame->Add(new Explosion(16,16,game))
doesn't work inside my object?
如果是这样,那么唯一可能的解释是 Entity
的 game
成员实际上并未指向 GameState
.检查它是否在施工中正确设置,并在使用前进行验证。
这与 std::set
无关。问题是您使用的 std::set
是您通过损坏的指针访问的类的一部分。
关于c++ - 使用 std::set of pointers 时出现段错误...谁能解释一下?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7052159/