C++ STL标准库 迭代器相关

发布时间 2023-03-26 18:28:48作者: 章章_思游容


迭代器是什么及用法详解

[迭代器是什么及用法详解 C语言中文网 ](http://c.biancheng.net/view/6675.html)

迭代器是C++ STL(标准模板库)中一种非常重要的概念,它提供了类似指针的行为让程序员可以对容器中的元素进行遍历、访问和修改等操作。

简单来说,迭代器就是一种抽象化的指针,它可以指向容器中的元素并支持指针相关的操作,例如解引用(*)、取地址(&)、自增(++)等等。通过迭代器,程序员可以在不关心底层容器类型和内部数据结构的情况下,对容器中的元素进行操作。

在C++中,STL库中的容器类(例如vector、list、set、map等)都提供了迭代器。容器的迭代器通常可以用begin()和end()成员函数获取,分别返回指向容器第一个元素和最后一个元素下一个位置的迭代器,可以使用迭代器来定位容器中的元素。

除了begin()和end()函数之外,STL库还提供了其他函数来对迭代器进行操作,例如advance()可以将迭代器向前或向后移动指定的位置,distance()可以计算两个迭代器之间的距离等等。

无论是序列容器还是关联容器,最常做的操作无疑是遍历容器中存储的元素,而实现此操作,多数情况会选用“迭代器(iterator)”来实现。那么,迭代器到底是什么呢?

我们知道,尽管不同容器的内部结构各异,但它们本质上都是用来存储大量数据的,换句话说,都是一串能存储多个数据的存储单元。因此,诸如数据的排序、查找、求和等需要对数据进行遍历的操作方法应该是类似的。

既然类似,完全可以利用泛型技术,将它们设计成适用所有容器的通用算法,从而将容器和算法分离开。但实现此目的需要有一个类似中介的装置,它除了要具有对容器进行遍历读写数据的能力之外,还要能对外隐藏容器的内部差异,从而以统一的界面向算法传送数据。

这是泛型思维发展的必然结果,于是迭代器就产生了。简单来讲,迭代器和 C++ 的指针非常类似,它可以是需要的任意类型,通过迭代器可以指向容器中的某个元素,如果需要,还可以对该元素进行读/写操作。

迭代器范围



C++ 迭代器怎么实现的?是通过操作符重载嘛

C++ 迭代器是通过类和操作符重载实现的。下面是一个迭代器类的简单实现:

点击查看代码

template <typename T>
class Iterator
 {
private:
    T* ptr;
public:
    explicit Iterator(T* p = nullptr) : ptr(p) {}
    Iterator(const Iterator<T>& it) : ptr(it.ptr) {}
    Iterator<T>& operator=(const Iterator<T>& it)
   {
        ptr = it.ptr;
        return *this;
    }

    Iterator<T>& operator++() 
   {
        ++ptr;
        return *this;
    }

    Iterator<T>& operator--() 
    {
        --ptr;
        return *this;
    }

    Iterator<T> operator++(int) 
  {
        Iterator<T> temp(*this);
        ++ptr;
        return temp;
    }

    Iterator<T> operator--(int) 
    {
        Iterator<T> temp(*this);
        --ptr;
        return temp;
    }

    T& operator*()
   {
        return *ptr;
    }

    T* operator->()
   {
        return ptr;
    }

    bool operator==(const Iterator<T>& it) {
        return ptr == it.ptr;
    }

    bool operator!=(const Iterator<T>& it) {
        return !(*this == it);
    }
};

上面代码中,我们通过重载操作符实现了迭代器的各种功能,例如 operator++ 和 operator-- 实现迭代器的自增和自减,operator* 实现解引用操作符,operator-> 实现成员访问操作符等等。当我们在 C++ 中使用迭代器时,我们可以将其视为指向容器中元素的指针,从而实现对容器元素的遍历或操作。


基本的迭代器有哪些?

在STL中,基本的迭代器类型如下:

  1. 输入迭代器(Input Iterator)
    输入迭代器可以遍历容器中的元素,并通过解引用运算符访问它们,但是不能移动迭代器位置,也不能对元素进行修改。例如,可以使用输入迭代器遍历一个流并读取流中的每一个元素,但是无法修改流中的元素。istream_iterator就是一个输入迭代器。

  2. 输出迭代器(Output Iterator)
    输出迭代器可以遍历容器中的元素,并通过解引用运算符访问它们,可以向容器中写入新的元素,但是不能移动迭代器位置。例如,可以使用输出迭代器向一个流中写入新的元素,但是无法修改流中的现有元素。ostream_iterator就是一个输出迭代器。

  3. 前向迭代器(Forward Iterator)
    前向迭代器可以遍历容器中的元素,并通过解引用运算符*访问它们,同时支持迭代器的自增操作(++),可以向前移动迭代器位置,并且可以对元素进行修改。这种迭代器通常用于链表的遍历。STL中的list和forward_list容器就提供了前向迭代器。

  4. 双向迭代器(Bidirectional Iterator)
    双向迭代器可以像前向迭代器一样访问和修改容器中的元素,并且支持逆向遍历元素,即可以使用--操作符将迭代器逆向移动。STL中的list、set、multiset、map、multimap等容器提供了双向迭代器。

  5. 随机访问迭代器(Random Access Iterator)
    随机访问迭代器可以像双向迭代器一样访问和修改容器中的元素,并且支持随机访问容器中的元素,即可以使用迭代器的加减、减减和下标操作符对元素进行定位和修改。STL中的vector、deque、array等容器提供了随机访问迭代器。
    不同类型的迭代器提供了不同的功能,选择合适类型的迭代器可以使程序的运行效率更高。



除了基本的迭代器之外,STL库还提供了多种类型的迭代器,

例如:

  1. 反向迭代器(reverse_iterator)
    反向迭代器是一种通过逆序访问容器中元素的迭代器,可以用rbegin()和rend()获取。例如,可以使用反向迭代器从后向前遍历一个vector中的元素。

  2. 常量迭代器(const_iterator)
    常量迭代器是一种不能修改容器中元素的迭代器,它指向容器中的元素,但是不能使用解引用运算符对元素进行修改。它可以使用cbegin()和cend()获取。

  3. 插入迭代器(insert_iterator)
    插入迭代器是一种向容器中插入元素的迭代器,它可以通过重载运算符,让程序员可以使用迭代器的方式向容器中插入元素。例如,可以使用插入迭代器将元素插入到vector、list等容器中的指定位置。

  4. 流迭代器(istream_iterator, ostream_iterator)
    流迭代器是一种让程序员可以以迭代器的方式对输入输出流进行遍历的迭代器,它可以使用istream_iterator和ostream_iterator创建,经常用来处理文件和网络数据流。

总的来说,不同类型的迭代器可以用来完成不同的任务,例如遍历、搜索、排序、删除等操作。