迭代器是指向容器内部元素的对象(如指针)。我们可以使用迭代器来遍历容器的内容。可以将它们可视化为类似于指向某个位置的指针的东西,我们可以使用它们在该特定位置访问内容。
迭代器在将算法与容器连接以及对容器内部存储的数据进行操作方面扮演着至关重要的角色。迭代器最明显的形式是指针。指针可以指向数组中的元素,并可以使用增量运算符(++)遍历它们。但是,所有迭代器都没有与指针相似的功能。
根据迭代器的功能,它们可分为五类,如下图所示,其中外层是功能最强大的,因此内层是功能最差的。
现在,STL中的所有容器都不支持这些迭代器中的每一个,不同的容器支持不同的迭代器,例如向量支持随机访问迭代器,而列表支持双向迭代器。整个列表如下所示:
迭代器的类型:根据迭代器的功能,它们可以分为五大类:
- 输入迭代器:它们是所有迭代器中最弱的,并且功能非常有限。它们只能在单遍算法中使用,即,按顺序处理容器的算法,这样就不会重复访问任何元素。
- 输出迭代器:与输入迭代器一样,它们的功能也非常有限,只能用于单遍算法中,但不能用于访问元素,而只能用于分配元素。
- 正向迭代器:它们在层次结构中比输入和输出迭代器要高,并且包含这两个迭代器中存在的所有功能。但是,顾名思义,它们也只能向前移动,一次也只能移动一步。
- 双向迭代器:它们具有前向迭代器的所有功能,并且克服了前向迭代器的缺点,因为它们可以在两个方向上移动,因此其名称是双向的。
- 随机访问迭代器:它们是功能最强大的迭代器。正如其名称所暗示的那样,它们不限于顺序移动,它们可以随机访问容器内的任何元素。它们的功能与指针相同。
下图显示了它们在执行各种操作方面的功能差异。
迭代器的好处
当然,有很多方法表明迭代器对我们非常有用,并鼓励我们深刻地使用它。使用迭代器的一些好处如下所示:
- 编程上的便利:最好使用迭代器遍历容器的内容,就像我们将不使用迭代器和使用[]运算符访问元素一样,那么我们需要始终担心容器的大小,而使用迭代器我们可以简单地使用成员函数end()并遍历所有内容,而不必记住任何事情。
// C++ program to demonstrate iterators #include
#include using namespace std; int main() { // Declaring a vector vector v = { 1, 2, 3 }; // Declaring an iterator vector ::iterator i; int j; cout << "Without iterators = "; // Accessing the elements without using iterators for (j = 0; j < 3; ++j) { cout << v[j] << " "; } cout << "\nWith iterators = "; // Accessing the elements using iterators for (i = v.begin(); i != v.end(); ++i) { cout << *i << " "; } // Adding one more element to vector v.push_back(4); cout << "\nWithout iterators = "; // Accessing the elements without using iterators for (j = 0; j < 4; ++j) { cout << v[j] << " "; } cout << "\nWith iterators = "; // Accessing the elements using iterators for (i = v.begin(); i != v.end(); ++i) { cout << *i << " "; } return 0; } 输出:
Without iterators = 1 2 3 With iterators = 1 2 3 Without iterators = 1 2 3 4 With iterators = 1 2 3 4
说明:从以上代码中可以看出,不使用迭代器,我们需要跟踪容器中的全部元素。开始时只有三个元素,但是在其中又插入了一个元素之后,因此也必须修改for循环,但是使用迭代器,for循环的时间保持不变。因此,迭代器简化了我们的任务。
- 代码的可重用性:现在考虑是否在上述程序中用v代替向量创建了一个列表,并且如果我们不使用迭代器来访问元素,而仅使用[]运算符,那么在这种情况下,这种访问方式对于列表(因为它们不支持随机访问迭代器)。
但是,如果我们对向量使用迭代器来访问元素,则只需更改向量以在迭代器的声明中列出即可达到目的,而无需执行其他任何操作
因此,迭代器支持代码的可重用性,因为它们可用于访问任何容器的元素。 - 动态处理容器:迭代器使我们能够在需要时轻松地动态地从容器中添加或删除元素。
// C++ program to demonstrate iterators #include
#include using namespace std; int main() { // Declaring a vector vector v = { 1, 2, 3 }; // Declaring an iterator vector ::iterator i; int j; // Inserting element using iterators for (i = v.begin(); i != v.end(); ++i) { if (i == v.begin()) { i = v.insert(i, 5); // inserting 5 at the beginning of v } } // v contains 5 1 2 3 // Deleting a element using iterators for (i = v.begin(); i != v.end(); ++i) { if (i == v.begin() + 1) { i = v.erase(i); // i now points to the element after the // deleted element } } // v contains 5 2 3 // Accessing the elements using iterators for (i = v.begin(); i != v.end(); ++i) { cout << *i << " "; } return 0; } 输出:
5 2 3
说明:如上面的代码所示,我们可以使用迭代器轻松动态地从容器中添加和删除元素,但是不使用它们而进行相同的操作将非常繁琐,因为它将需要在插入之前和之后每次都移动元素删除。