【问题标题】:Iterator = pointer? Or what is it?迭代器 = 指针?或者它是什么?
【发布时间】:2015-09-06 03:41:01
【问题描述】:

C++ 中的迭代器是指针吗?我问的原因是似乎没有人完全理解迭代器是什么。这只是他们所说的“事物”或“价值”。但是迭代器只是指向元素,指向它的位置。当我们取消引用它时,就像查看迭代器指向的内容一样。

这个比喻正确吗?

【问题讨论】:

标签: c++ iterator


【解决方案1】:

简短的回答是:

  • 指针是一种迭代器。
  • 因此可以将指针用作迭代器。
  • 指针具有迭代器以外的属性。

历史

历史上,我们有 C 指针,当 C++ 发明时,它被改编成 C++。指针表示内存中的一个位置,因此可以用作数组中的一个位置。

后来,在 1990 年代,一种称为“迭代器概念”的思想被引入 C++。 “迭代器概念”与称为 STL 的库(后来被标准库吸收)和称为“泛型编程”的范例有关。迭代器概念的灵感来自 C 指针,用于表示容器中的位置,如 vectordeque 等,就像 C 指针如何表示数组中的位置一样。 迭代器概念经过精心设计以兼容 C 指针,因此我们现在可以说 C 指针模型迭代器概念

迭代器概念

理解迭代器概念的一种简化方法是,如果一种数据类型支持操作和行为列表,例如它表示容器中的一个位置,并允许对元素进行某种访问,则它可以称为迭代器。

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

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

指针的其他属性

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

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

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

【讨论】:

    【解决方案2】:

    没有。迭代器不仅仅是“一个指针”。

    在某些情况下,迭代器可以是一个指针——但它可以更多。迭代器是指针作用的概括。

    当您增加一个指针时,它会前进到内存中的下一个位置(以您正在处理的对象的大小为模)。当您增加迭代器时,它会前进到“序列中的下一个元素”。如果您正在使用链表,它将前进到列表中的下一个元素。如果您正在使用地图或集合,则到地图/集合中的下一个元素,依此类推。

    【讨论】:

    • 我明白了。如果我们有一个来自 C 的经典数组,所有元素在内存中看起来就像一条直线,这就是为什么递增指针使其指向下一个元素的原因。与列表相反,列表中的元素可以在内存中以随机顺序排列,但是递增迭代器将使其指向下一个元素,而不管该元素在内存中的位置。感谢您的有用说明。
    【解决方案3】:

    迭代器比指针更通用。在它不是指针的情况下,它只是一个具有自定义operator++()operator++(int)operator--()operator--(int)operator->()operator*() 等的普通类。您可以实现您的任何行为我喜欢这些运营商。这里没有什么神奇的。

    【讨论】:

      【解决方案4】:

      迭代器只是一个可用于迭代容器中元素的对象。有不同类别的迭代器。不同之处在于它们支持哪些操作,例如使用 Forward 迭代器,您可以使用 ++ 从一个元素转到下一个元素,使用 Random 访问迭代器,您可以一步从一个元素转到另一个元素。

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

      迭代器通常是包含一个指针的结构,该指针被赋予一个通用接口,容器可以使用该接口来遍历它们的元素。不过,情况并非总是如此。在标准容器的一些实现中,std::vector::iterator,例如iterator仅仅被定义为typedef T* iterator

      实际上,指针和迭代器之间的区别实际上取决于迭代器的实现。

      【讨论】:

        【解决方案5】:

        在 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&lt;T&gt;::const_iterator 是一个重载了++* 运算符的类,因此它看起来像一个指向数组元素的指针。在幕后,++ 运算符跟随集合内部树结构中的链接移动到下一个元素。

        std::vectorstd::string 类也有迭代器,但因为这些类是经典数组的包装器,所以它们很可能只是相应指针类型的 typedef。

        迭代器也可以用于循环中迭代变量以外的事情。例如,容器通常有一个 find 方法,该方法将迭代器返回到它找到的对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-13
          • 2014-12-05
          • 2013-04-04
          • 2012-08-23
          • 1970-01-01
          • 2015-09-16
          • 2017-04-04
          • 2019-11-10
          相关资源
          最近更新 更多