C++地图可以包含指向我任意类的指针吗?

fin*_*bob 0 c++ pointers stl map

我正在编写一个小型游戏引擎作为夏季项目,并且正在与STL地图挣扎.

我已经声明了一个类RenderList来保存对象.RenderList将传递给一个Renderer类来完成工作.

RenderListmap<std::string,Entity*> objects;

这一切都有效,直到我试图Entity*从地图中获得一个,我得到:

断言失败,在vc/include/xtree中表达式:map/set iterator not dereferencable.

这是检索指针的代码.

Entity* RenderList::getByName(std::string str){
    return objects.find(str)->second;
}
Run Code Online (Sandbox Code Playgroud)

我需要它来保持指针而不是实际的对象,因为Entity我需要不同的子类.

我是STL的新手,我不应该在地图中存储指针吗?

当然我应该被允许这样做,或者更好的想法来存储对象?

最后,我只是做错了!?

希望这个问题不重复,我事先做了快速搜索.如果这在GameDev Stack中更好,我会在那里发布.

Jon*_*ely 8

如果未找到该键,则map::find(key)返回"past-the-end"迭代器,即返回的值map::end(),并且迭代器不指向任何元素,因此无法解除引用.find在解除引用之前,您不会检查返回的内容.

你确定他们的钥匙在地图上吗?

如果找不到密钥,您可能希望执行类似返回NULL的操作,您可以通过将返回的迭代器与end例如比较来检查.

Entity* RenderList::getByName(std::string str){
  map_type::iterator it = objects.find(str);
  if (it == objects.end())
    return NULL;
  return it->second;
}
Run Code Online (Sandbox Code Playgroud)

在哪里RenderList定义typedef:

typedef map<std::string,Entity*> map_type;
Run Code Online (Sandbox Code Playgroud)

(注意,我总是让我的类为我用作实现细节的容器定义typedef,因为它map_type::iterator比编写容易得多map<std::string,Entity*>::iterator,因为如果我将容器更改为其他东西,我不必更改使用它的所有代码,例如map<std::string,shared_ptr<Entity>>::iterator我可以把它留下来map_type::iterator,它仍然可以正常工作.)

关于一般设计,你可以存储boost::shared_ptr<Entity>std::tr1::shared_ptr<Entity>代替原始指针吗?管理对象生命周期将更安全,更简单.