让我们考虑这个类:
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
and中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
方法应该存在并按值返回。但是我也在考虑编译器警告。