在C++中,迭代器是指针吗?

18

C++中的迭代器是指针吗?我问这个问题是因为似乎没有人完全理解什么是迭代器。他们只是说它是一个“东西”或“值”。但是,迭代器只是指向元素及其位置的简单指针。当我们对其进行解引用时,就像查看迭代器指向的内容。

这个类比正确吗?


1
迭代器和指针有什么关系? - MartianMartian
5个回答

16

简短的回答是:

  • 指针是一种迭代器。
  • 因此,指针可以用作迭代器。
  • 指针具有其他属性,而不仅仅是迭代器。

历史

从历史上看,我们有 C 指针,并且在发明 C++ 时将其适应为 C++。指针表示内存中的位置,因此可以用作数组中的位置。

后来,在 1990 年代,引入了一个称为“迭代器概念”的想法到 C++ 中。 “迭代器概念”与一个名为 STL 的库(后来被吸收到标准库中)和一个称为“通用编程”的范例相关。迭代器概念受到 C 指针的启发,以表示容器中的位置,例如 vectordeque 等,就像 C 指针表示数组中的位置一样。 迭代器概念经过精心设计,以与 C 指针兼容,因此我们现在可以说 C 指针模拟了迭代器概念

迭代器概念

理解迭代器概念的一种简化方式是,如果数据类型支持一系列操作和行为,以便表示容器中的位置,并启用对元素的某种访问,则可以称其为迭代器。

通过仔细设计迭代器概念,C指针实现了该列表。因此,指针是一种迭代器。

迭代器概念只是对类型的一组要求,这意味着您可以通过C++数据抽象的强大功能创建自己的迭代器。

指针的其他属性

指针具有其他属性,与迭代器概念无关。

指针的一个重要用途是表达引用语义,即引用远程内存位置中的对象。这种指针的使用后来被认为是不安全的,并导致“智能指针”的发明。通过比较智能指针和迭代器,我们可以发现它们是完全不相关的概念。

指针的另一个用途是引用原始内存位置。这对于应用程序编程来说完全不安全,但对于微控制器编程来说是一种必不可少的操作硬件的工具。


5
不是。迭代器不仅仅是一个指针。在某些情况下,迭代器可以是指针,但它可以更多。迭代器是指针所做的事情的一般化。当你递增指针时,它会在内存中的下一个位置(模大小为您正在处理的对象)上前进。当你递增迭代器时,它会前进到“序列中的下一个元素”。如果您正在使用链接列表,则会前进到列表中的下一个元素。如果您正在使用地图或集合,则会前进到地图/集合中的下一个元素,依此类推。

2
我明白了。如果我们有来自 C 的经典数组,所有元素在内存中看起来像是一条直线,这就是为什么通过增加指针可以将其指向下一个元素。与列表相反,其中元素可以以任意顺序存储在内存中,但增加迭代器将使其指向下一个元素,而不管元素在内存中的位置如何。感谢您提供的有用信息。 - trollpidor

1

在C语言中,您可以使用一个简单的for循环和指针变量来遍历数组,例如:

int arr[MAX];

for (int* p = arr; p < arr + MAX; ++p)
{
    do_something_with(*p);
}

这是因为数组在内存中是连续存储的。但对于其他类型的数据结构(如链表、树、哈希表等),移动到容器的下一个元素所需的代码比简单的++更复杂。
C++迭代器类似于指针,但可以泛化到所有类型的容器。
std::set<int> s;

for (std::set<int>::const_iterator it = s.begin(); it != s.end(); ++it)
{
    do_something_with(*it);
}
std::set<T>::const_iterator是一个类,它重载了++*运算符,使其看起来像数组元素的指针。在幕后,++运算符遵循集合内部树结构中的链接以移动到下一个元素。 std::vectorstd::string类也有迭代器,但由于这些类是经典数组的包装器,因此这些迭代器可能只是相应指针类型的typedef。
迭代器还可以用于循环中的迭代变量之外的其他事情。例如,容器通常具有返回找到的对象的迭代器的find方法。

1

迭代器比指针更通用。如果不是指针,则只是一个普通的类,具有自定义的 operator++()operator++(int)operator--()operator--(int)operator->()operator*() 等操作符。您可以在这些操作符中实现任何行为,没有什么神奇的地方。


1
迭代器是一个可用于遍历容器中元素的对象。有不同类型的迭代器,它们之间的区别在于支持的操作不同。例如,使用前向迭代器可以使用 ++ 前进到下一个元素,而使用随机访问迭代器可以一步到达另一个元素。

http://www.cplusplus.com/reference/iterator/

迭代器通常是包含指针的结构,这些结构提供了容器可以用来遍历其元素的公共接口。但并非总是如此。在一些标准容器的实现中,例如 std::vector::iteratoriterator 只被定义为 typedef T* iterator
实际上,指针和迭代器之间的区别取决于迭代器的实现方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接