我有一个类Point
,该类具有一个获取位置的成员方法:
class Point {
private:
int x; int y;
public:
Point(int a, int b) {
x = a; y = b;
}
int getX() { return x; }
int getY() { return y; }
};
这些存储在名为list<Point>
的{{1}}中。我有一个检查位置是否与列表中任何点匹配的函数:
listPoints
请注意,bool checkMatch(int x, int y) {
for (Point p : listPoints) {
if (p.getX() == x && p.getY() == y) {
return true;
}
}
return false;
}
用于访问.
的成员方法,但是还有另一种方法:
Point
此函数与以前的函数有何不同,特别是为什么bool checkMatch(int x, int y) {
list<Point>::iterator p = listPoints.begin();
for (; p != listPoints.end(); ++p) {
if (p->getX() == x && p->getY() == y) {
return true;
}
}
return false;
}
不再起作用,为什么我需要使用.
来访问->
的成员方法?这些foreach循环有根本的不同吗?
答案 0 :(得分:1)
这些foreach循环是否根本不同?
它们在本质上没有什么不同。它们有些微不同。
类似于:
int a;
int* ptr = &a;
a = 10;
*ptr = 10;
最后两行在本质上没有不同。迭代器有点像指针。它的operator*
重载,因此使用*p
的行为就好像您要取消引用指针一样-您可以引用容器中的某个项目。
第二个代码块可以更改为类似于第一个代码块。
list<Point>::iterator iter = listPoints.begin();
for (; iter != listPoints.end(); ++iter) {
Point& p = *iter;
if (p.getX() == x && p.getY() == y) {
return true;
}
}
在幕后,第一个方块就是那个。
有关详细信息,请参见documentation on the range-for
loop in the standard。
答案 1 :(得分:1)
它们没有什么不同,除了一些非常小的例外。在第二个循环中,您使用的是迭代器,它或多或少是指向对象本身的指针。可以取消引用以获取实际对象。
如果要删除某些元素,则可以使用迭代器。因此,您要删除匹配项,而不是检查匹配项,而是要使用迭代器进行迭代。
由于您只是在整个范围内进行迭代,因此使用for-ranged循环要清晰得多。更加容易编写和清晰。
具体为什么。不再工作,我需要使用->来访问Point的成员方法?
因为iterator
是一个对象,它基本上指向实际对象。您无法覆盖点运算符,因此将替代operator->
来检索对象。也可以像iterator
一样解除对*p
的引用,这允许您使用点运算符(*p).getX()