Foreach循环和箭头/点运算符的区别?

时间:2019-03-15 03:17:14

标签: c++ for-loop foreach iterator

我有一个类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循环有根本的不同吗?

2 个答案:

答案 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()