Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从STL映射迭代器获取字段_C++_Map_Iterator_Std Pair - Fatal编程技术网

C++ 从STL映射迭代器获取字段

C++ 从STL映射迭代器获取字段,c++,map,iterator,std-pair,C++,Map,Iterator,Std Pair,我有一个地图容器来存储某些对象及其名称和类型: typedef std::map<std::string, std::pair<ObjType, ObjBase*> > ObjContainer; 显然,许多“it->second.second”不是很清楚,而且无法维护。 如果它在将来被更改,以支持一个或多个字段,例如,它将全部断开。 因此,我试图通过函数来更改它们以访问字段,如下所示: ObjContainer::iterator it = mObjContainer

我有一个地图容器来存储某些对象及其名称和类型:

typedef std::map<std::string, std::pair<ObjType, ObjBase*> > ObjContainer;
显然,许多“it->second.second”不是很清楚,而且无法维护。 如果它在将来被更改,以支持一个或多个字段,例如,它将全部断开。 因此,我试图通过函数来更改它们以访问字段,如下所示:

ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    if (it->second.second) {
        it->second.second->setObj2Default();
        delete it->second.second;
        it->second.second = 0;
    }
}
ObjBase*& getObjPtr(ObjContainer::iterator it) {
    return it->second.second;
}
同样,还需要函数getObjName和getObjType

还有人向我建议,让迭代器返回这些字段会更清楚:

 it.objPtr();
 it.objName();
 it.objType();
但是我认为STL迭代器不应该被继承来拥有这些函数,对吗?除了为映射创建一个包装器,并使用自己的迭代器和这些函数之外,我看不到其他方法


那么,什么才是最合适的选择呢?有没有其他方法可以解决我没有看到的这个问题?

我只需要制作一个指针(或引用)的本地副本——它可能会被优化掉:

ObjContainer::iterator const it = mObjContainer.find(name);
if (it != mObjContainer.end())
{
    ObjBase * & p = it->second.second;
    if (p) { p->foo(); delete p; p = NULL; }
}

使用引用来简化语法

ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    std::pair<ObjType, ObjBase*> & ref = it->second;
    if (ref.second) { // ...
ObjContainer::iterator it=mObjContainer.find(name);
if(it!=mObjContainer.end()){
std::pair&ref=it->second;
如果(参考秒){/。。。

如果最大的问题是可维护性,我将用一个自定义类/结构替换std::pair,该类/结构将ObjType和ObjBase*包装为一个

  • 在混合中添加新字段很容易
  • 很容易访问结构字段ObjType和ObjPair
  • 为处理ObjType和ObjPair的类编写getter/setter/其他函数很容易

我首先要问自己ObjType是否是强制性的。 如果目的只是告诉第二个ObjBase*参数实际指向的类是什么类型的,请使用
dynamic\u cast
并去掉该对

typedef std::map<std::string, ObjBase*> ObjContainer;
当您需要测试对象的实际类型时:

ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    if (ChildObj* p_Child = dynamic_cast<ChildObj*>(it->second)) {
        // Work on p_Child...
    }
}
ObjContainer::iterator it=mObjContainer.find(name);
if(it!=mObjContainer.end()){
如果(ChildObj*p_Child=dynamic_cast(it->second)){
//关于p_儿童的工作。。。
}
}

你为什么不使用一个结构而不是一对,并按照你想要的方式命名你的字段?@Spidey:如果库已经有了一个完全可用的类定义,为什么还要滚动你自己的类定义呢?你可以用acessor来包装它们。至少你不用pair.first,pair.second,pair->second->second,等等。不,对象类型是needed,因为有时候ObjBase*将为null,并且它们的ObbType可用于使用工厂构建新实例。
ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
    if (ChildObj* p_Child = dynamic_cast<ChildObj*>(it->second)) {
        // Work on p_Child...
    }
}