C++映射是否可以包含指向我的任意类的指针
Can a C++ map contain a pointer to my arbitrary class?
我正在编写一个小型游戏引擎作为夏季项目,并且在STL映射方面有点困难。
我已经声明了一个类RenderList
来保存对象。RenderList将被传递给Renderer
类来完成这项工作。
RenderList
具有map<std::string,Entity*> objects;
这一切都有效,直到我试图从地图上获得Entity*
,我得到了:
断言失败,在vc/include/xtree中表达式:映射/设置迭代器不可取消引用。
这是用于检索指针的代码。
Entity* RenderList::getByName(std::string str){
return objects.find(str)->second;
}
我需要它来容纳指针,而不是实际的对象,因为我需要Entity
的不同子类。
我是STL的新手,我应该不在映射中存储指针吗?
当然应该允许我这样做,还是存储对象更好?
最后,我只是做错了吗!?
希望这个问题不是重复的,我事先做了快速搜索。此外,如果这在GameDev堆栈中会更好,我会把它发布在那里。
如果找不到键,则map::find(key)
返回一个"结束后"迭代器,即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;
}
其中RenderList
定义typedef:
typedef map<std::string,Entity*> map_type;
(注意:我总是让我的类为我用作实现细节的容器定义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>
而不是原始指针吗?管理对象的生存期会更安全、更简单。
这可能意味着您要查找的名称在映射中不存在。如果键不存在,find
方法将返回映射的结束迭代器,该迭代器实际上是不可解引用的。
如果"未找到"的情况是自然发生的,那么你可以做这个
Entity* RenderList::getByName(std::string str){
map<std::string,Entity*>::iterator it = objects.find(str);
return it != objects.end() ? it->second : NULL;
}
从而将处理这种情况的责任传递给呼叫者。
如果"未找到"的情况不应该发生,要么抛出异常,要么至少执行
assert(it != objects.end());
其中一个错误是,您需要处理没有与str
匹配的条目的情况。然而,我不确定具体的错误是什么,因为我(遗憾地)在地图上做了同样的搜索来检索指针。。
如果映射不包含传递给find
方法的键,那么它将返回objects.end()
。取消引用这是一个运行时错误,很可能会导致您看到的错误。尝试:
map<std::string,Entity*>::iterator findIt;
findIt = objects.find(str);
if ( findIt != objects.end() )
{
return findIt->second;
}
else
{
// Handle error here
}
正如其他人所指出的,您正在查找的名称在地图中不存在。每个人都很快建议您检查.find()
的返回值。相反,我建议您不要拨打.find()
。以下是我将如何解决您的问题:
Entity* RenderList::getByName(std::string str){
return objects[str];
}
在上面的代码中,查找一个不存在的映射条目将创建一个指针值为NULL的条目,并返回NULL。
您需要在的某个地方添加一些代码来检查空指针,然后再对其进行尊重。
- 为什么我的好友类无法访问私人会员?
- 为我的 c++ 类介绍制作一个三角形分类器.我有几个问题
- 我的模板类方法返回错误类型?
- 我的超类中的模板问题与结构定义
- 为什么我的子类不继承父类的字符串?
- 获取我的基类以递增派生类对象整数
- 我的子类的属性是延迟初始化的
- 是否允许调用方对我的 Builder 类使用任何指针类型(包括智能指针)?
- 我可以说服自动生成的构造函数将我的 POD 类成员归零吗?
- 无法在 cuda 内核中使用我的模板类
- 我无法重写基类的方法,因为我的派生类是模板化的
- 我的 ArrayList 类重新分配中的分段错误
- 我的字符串类的 += 运算符有问题,它没有正确连接字符串
- 尝试在我的基类中启动线程时,Visual Studio 由于调试错误而中止我的程序
- 为什么我的Protobuf类可以解析由其他Protobuf类串联的字符串
- 我可以从我的超类调用子类构造函数吗?
- 从C 中的任意类继承
- G++ 在编译我的 flex 和 bison 代码时无法识别我的 c++ 类
- 在我的模板类示例中,发生“分段错误(核心转储)”错误
- C++映射是否可以包含指向我的任意类的指针