作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
让我们考虑一下这个类:
class X {
std::map<uint32_t, uint32_t> _map;
public:
X() { /* Populate the map */ }
std::map<uint32_t, uint32_t> getTheMap() { return _map; }
};
还有这个有问题的代码:
X x;
// Statement 1
std::map<uint32_t, uint32_t>::const_iterator it = x.getTheMap().begin();
// Statement 2
std::map<uint32_t, uint32_t>::const_iterator et = x.getTheMap().end();
for (; it != et; it++) {
/* Access the map using the iterator it */
}
错误的部分是,在 Statement 1
和 Statement 2
中,我得到了一个指向临时对象的迭代器,该对象将在每一个陈述。因此,for()
循环内的行为是未定义的。
getTheMap()
方法的正确用法应该是这样的:
std::map<uint32_t, uint32_t> map = x.getTheMap();
std::map<uint32_t, uint32_t>::const_iterator it = map.begin();
std::map<uint32_t, uint32_t>::const_iterator et = map.end();
for (/* [...] */)
必须注意类 X
有一些严重的设计问题:
_map
应该更好地封装在类中(读写访问),因此可以避免 getTheMap()
方法getTheMap()
方法,它可以返回对 _map
的引用但是,如果“按原样”给定 X 类(<-- 请参阅下面的编辑),是否有办法阻止用户将迭代器获取到临时值?
编辑:类 X
可以更改,但 getTheMap
方法应该存在并按值返回。但是我也在考虑编译器警告。
最佳答案
一种可能是使用这样的包装器:
class X {
typedef std::map<uint32_t,uint32_t> Map;
Map _map;
struct MapWrap {
const Map &mapref;
MapWrap(const Map &mapref_arg)
: mapref(mapref_arg)
{
}
operator Map() const { return mapref; }
};
public:
MapWrap getTheMap()
{
return MapWrap(_map);
}
};
所以你得到这个:
X x;
std::map<uint32_t,uint32_t>::const_iterator iter = x.getTheMap().begin(); // error
std::map<uint32_t,uint32_t> m = x.getTheMap(); // no error
这可以防止意外使用像 map 这样的临时文件,但会使其成为用户必须使用 map 拷贝的地方。
关于c++ - 使用临时对象将迭代器获取到 STL 容器时出现细微错误 : how to avoid it?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9806094/
我是一名优秀的程序员,十分优秀!