迭代器与容器本身不同。迭代器引用容器中的单个项目,并提供访问其他项目的方法。
考虑设计您自己的不带迭代器的容器。它可以有一个size 函数来获取它包含的项目数,并且可以重载[] 运算符以允许您通过其位置获取或设置一个项目。
但是这种“随机访问”并不容易在某些容器上有效地实现。如果您获得第 100 万个项目:c[1000000],并且容器内部使用链表,则它必须扫描一百万个项目才能找到您想要的。
您可能会决定允许集合记住“当前”项。它可以具有 start 和 more 和 next 之类的功能,以允许您循环浏览内容:
c.start();
while (c.more())
{
item_t item = c.next();
// use the item somehow
}
但这会将“迭代状态”放入容器中。这是一个严重的限制。如果您想将容器中的每个项目与其他所有项目进行比较怎么办?这需要两个嵌套循环,都遍历所有项目。如果容器本身存储了迭代的位置,你就没有办法嵌套两个这样的迭代——内循环会破坏外循环的工作。
所以迭代器是迭代状态的独立副本。您可以开始迭代:
container_t::iterator i = c.begin();
那个迭代器,i,是一个单独的对象,代表容器中的一个位置。您可以获取存储在该位置的任何内容:
item_t item = *i;
您可以移至下一项:
i++;
使用一些迭代器,您可以向前跳过几个项目:
i += 1000;
或者在相对于迭代器标识的位置的某个位置获取项目:
item_t item = i[1000];
使用一些迭代器,您可以向后移动。
您可以通过将迭代器与end 进行比较来发现是否超出了容器的内容:
while (i != c.end())
您可以将end 视为返回一个迭代器,该迭代器表示一个位置,该位置超出容器中的最后一个位置。
使用迭代器(通常在 C++ 中)需要注意的重要一点是它们可能会变得无效。例如,如果您清空一个容器,通常会发生这种情况:任何指向该容器中位置的迭代器现在都变得无效。在那种状态下,对它们的大多数操作都是未定义的——任何事情都可能发生!