代码之家  ›  专栏  ›  技术社区  ›  gator

Foreach循环与arrow/dot运算符的区别?

  •  0
  • gator  · 技术社区  · 5 年前

    我有一节课 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> 命名的 listPoints . 我有一个函数可以检查一个位置是否与列表中的任何点匹配:

    bool checkMatch(int x, int y) {
        for (Point p : listPoints) {
            if (p.getX() == x && p.getY() == y) {
                return true;
            }
        }
        return false;
    }
    

    注意 . 用于访问的成员方法 ,但还有另一种方法:

    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 回复  |  直到 5 年前
        1
  •  1
  •   Tas    5 年前

    他们没什么不同不,除了一些很小的例外。在第二个循环中,您使用的是迭代器,它或多或少是指向对象本身的指针。它可以被解引用以获得实际的对象。

    如果要删除某些元素,可以使用迭代器。所以说,不是检查匹配项,而是删除任何匹配项,而是使用迭代器进行迭代。

    因为您只是在整个范围内迭代,所以使用for-ranged循环要清楚得多。写起来更容易,也更清楚。

    具体原因。不再工作,我需要使用->来访问点的成员方法?

    因为 iterator 是一个对象,它基本上指向实际的对象。不能重写点运算符,因此 operator-> 重写以检索对象。也可以取消引用 迭代器 喜欢 *p ,它允许您使用点运算符 (*p).getX()

        2
  •  1
  •   R Sahu    5 年前

    这些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 详细情况。