我有一个地图容器来存储某些对象及其名称和类型:
typedef std::map<std::string, std::pair<ObjType, ObjBase*> > ObjContainer;
但是,在代码的许多部分中,都有这样的结构:
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迭代器来拥有那些函数,对吧?除了为地图创建一个包装器并拥有自己的带有这些函数的迭代器之外,我没有其他方法可以做到这一点。
那么,最合适的选择是什么?还有其他方法可以解决我没有看到的这个问题吗?
答案 0 :(得分:4)
如果最大的问题是可维护性,我会用一个自定义类/结构替换std :: pair,它将ObjType和ObjBase *包装为一个。
答案 1 :(得分:2)
我只是制作指针(或参考)的本地副本 - 它可能会被优化掉:
ObjContainer::iterator const it = mObjContainer.find(name);
if (it != mObjContainer.end())
{
ObjBase * & p = it->second.second;
if (p) { p->foo(); delete p; p = NULL; }
}
答案 2 :(得分:0)
使用引用来简化语法。
ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
std::pair<ObjType, ObjBase*> & ref = it->second;
if (ref.second) { // ...
答案 3 :(得分:0)
我首先询问自己ObjType是否是强制性的。
如果目的只是告诉该对的第二个ObjBase *参数实际指向哪个类,请使用dynamic_cast
并删除该对。
typedef std::map<std::string, ObjBase*> ObjContainer;
代码中不再有second.second
:
ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
if (it->second) {
it->second->setObj2Default();
delete it->second;
it->second = NULL;
}
}
当你需要测试对象的实际类型时:
ObjContainer::iterator it = mObjContainer.find(name);
if (it != mObjContainer.end()) {
if (ChildObj* p_Child = dynamic_cast<ChildObj*>(it->second)) {
// Work on p_Child...
}
}