【发布时间】:2015-09-06 03:41:01
【问题描述】:
C++ 中的迭代器是指针吗?我问的原因是似乎没有人完全理解迭代器是什么。这只是他们所说的“事物”或“价值”。但是迭代器只是指向元素,指向它的位置。当我们取消引用它时,就像查看迭代器指向的内容一样。
这个比喻正确吗?
【问题讨论】:
C++ 中的迭代器是指针吗?我问的原因是似乎没有人完全理解迭代器是什么。这只是他们所说的“事物”或“价值”。但是迭代器只是指向元素,指向它的位置。当我们取消引用它时,就像查看迭代器指向的内容一样。
这个比喻正确吗?
【问题讨论】:
简短的回答是:
历史上,我们有 C 指针,当 C++ 发明时,它被改编成 C++。指针表示内存中的一个位置,因此可以用作数组中的一个位置。
后来,在 1990 年代,一种称为“迭代器概念”的思想被引入 C++。 “迭代器概念”与称为 STL 的库(后来被标准库吸收)和称为“泛型编程”的范例有关。迭代器概念的灵感来自 C 指针,用于表示容器中的位置,如 vector、deque 等,就像 C 指针如何表示数组中的位置一样。 迭代器概念经过精心设计以兼容 C 指针,因此我们现在可以说 C 指针模型迭代器概念。
理解迭代器概念的一种简化方法是,如果一种数据类型支持操作和行为列表,例如它表示容器中的一个位置,并允许对元素进行某种访问,则它可以称为迭代器。
通过精心设计的迭代器概念,C 指针实现了该列表。因此,指针是一种迭代器。
迭代器概念只是对类型的一组要求,意味着您可以通过 C++ 的数据抽象能力创建自己的迭代器。
指针还有其他属性,与迭代器概念无关。
指针的一个重要用途是表达引用语义,即引用远程内存位置中的对象。这种指针的使用后来被认为是不安全的,并导致了“智能指针”的发明。通过比较智能指针和迭代器,我们可以发现它们是完全不相关的概念。
指针的另一个用途是引用原始内存位置。这对于应用程序编程来说是完全不安全的,但对于微控制器编程来操作硬件来说却是必不可少的工具。
【讨论】:
没有。迭代器不仅仅是“一个指针”。
在某些情况下,迭代器可以是一个指针——但它可以更多。迭代器是指针作用的概括。
当您增加一个指针时,它会前进到内存中的下一个位置(以您正在处理的对象的大小为模)。当您增加迭代器时,它会前进到“序列中的下一个元素”。如果您正在使用链表,它将前进到列表中的下一个元素。如果您正在使用地图或集合,则到地图/集合中的下一个元素,依此类推。
【讨论】:
迭代器比指针更通用。在它不是指针的情况下,它只是一个具有自定义operator++()、operator++(int)、operator--()、operator--(int)、operator->()、operator*() 等的普通类。您可以实现您的任何行为我喜欢这些运营商。这里没有什么神奇的。
【讨论】:
迭代器只是一个可用于迭代容器中元素的对象。有不同类别的迭代器。不同之处在于它们支持哪些操作,例如使用 Forward 迭代器,您可以使用 ++ 从一个元素转到下一个元素,使用 Random 访问迭代器,您可以一步从一个元素转到另一个元素。
http://www.cplusplus.com/reference/iterator/
迭代器通常是包含一个指针的结构,该指针被赋予一个通用接口,容器可以使用该接口来遍历它们的元素。不过,情况并非总是如此。在标准容器的一些实现中,std::vector::iterator,例如iterator仅仅被定义为typedef T* iterator
实际上,指针和迭代器之间的区别实际上取决于迭代器的实现。
【讨论】:
在 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::vector 和 std::string 类也有迭代器,但因为这些类是经典数组的包装器,所以它们很可能只是相应指针类型的 typedef。
迭代器也可以用于循环中迭代变量以外的事情。例如,容器通常有一个 find 方法,该方法将迭代器返回到它找到的对象。
【讨论】: