资源描述
什么是C++的迭代器Interator?
容器就是数据结构的泛指,迭代器就是指针的泛指,可以指向元素。容器相当于一个储藏柜,里面装的许多不同的物品就像是储存的元素,比如面包、啤酒、苹果、现金。要取得各个物体就得用与各个物体向匹配的工具,如取出面包要用盘子、取出啤酒要用杯子、取出苹果要用篮子、取出现金要用钱包。迭代器的作用就相当于取出物品的工具的抽象,通过迭代器泛指现实生活中从贮藏室中取出物体的工具。C++迭代器是一种检查容器内元素并遍历元素的数据类型。
1 Iterator definitions
In C++, an iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (at least, the increment (++) and dereference (*) operators).
The most obvious form of iterator is a pointer: A pointer can point to elements in an array, and can iterate through them using the increment operator (++). But other forms of iterators exist. For example, each container type (such as a vector) has a specific iterator type designed to iterate through its elements in an efficient way.
C++迭代器Interator就是一个指向某种STL对象的指针。通过该指针可以简单方便地遍历所有元素。
C++中的iterator为STL中的重要概念。iterator的概念源自于对遍历一个线性容器工具的抽象,即如何你能访问这个容器的某个元素。对于最简单的数组,当然可以用数组的索引值,因为数组是连续存放在内存中的;但对于链表,就必须用指针。除此之外,还有还有很多种数据结构需要提供一个方便的工具来访问其中的元素,方法有ID,关键字等等。为了统一所有的容器的这种工具的使用,一般提供一整套容器的开发者就会用一种方式来表示各种容器的访问工具。例如C++ STL就是使用iterator。MFC自己的容器使用position。C#和java也有自己的方法,但方法是不变的。
iterator的用法可以被统一,但不同的底层容器实现其iterator的原理是不一样的。例如iterator++你可以理解为移动到容器的下一个元素,如果底层如果是数组,把索引值加一就行;如果底层是链表,就得执行类似于m_pCurrent = m_pCurrent-> pNext;的操作。因此每种容器都有自己的iterator实现方法。
C++ STL iterator的常用方法有:
iterator++ 移到下个元素
iterator-- 移到上个元素
*iterator 访问iterator所指元素的值
< > == != iterator之间的比较,例如判断哪个元素在前
iterator1 + iterator2 iterator之间的加法运算,类似于指针加法
2 容器的 iterator 类型
每种容器类型都定义了自己的C++迭代器类型,如 vector:vector<int>::iterator iter;这符语句定义了一个名为 iter 的变量,它的数据类型是 vector<int> 定义的 iterator 类型。每个标准库容器类型都定义了一个名为 iterator 的成员,这里的 iterator 与迭代器实际类型的含义相同。
begin 和 end 操作每种容器都定义了一对命名为 begin 和 end 的函数,用于返回迭代器。如果容器中有元素的话,由 begin 返回的迭代器指向第一个元素:
vector<int>::iterator iter = ivec.begin();
上述语句把 iter 初始化为由名为 vector 操作返回的值。假设 vector 不空,初始化后,iter 即指该元素为ivec[0]。
由 end 操作返回的C++迭代器指向 vector 的“末端元素的下一个”。“超出末端迭代器”(off-the-end iterator)。表明它指向了一个不存在的元素。如果 vector 为空,begin 返回的迭代器与 end 返回的迭代器相同。由 end 操作返回的迭代器并不指向 vector 中任何实际的元素,相反,它只是起一个哨兵(sentinel)的作用,表示我们已处理完 vector 中所有元素。
a)使用迭代器读取vector中的每一个元素
vector<int> ivec(10,1);
for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();++iter)
{
*iter=2; //使用 * 访问迭代器所指向的元素
}
b)const_iterator只能读取容器中的元素,而不能修改
for(vector<int>::const_iterator citer=ivec.begin();citer!=ivec.end();citer++)
{
cout<<*citer;
//*citer=3; error
}
3 vector 迭代器的自增和解引用运算
C++迭代器类型定义了一些操作来获取迭代器所指向的元素,并允许程序员将迭代器从一个元素移动到另一个元素。迭代器类型可使用解引用操作符(dereference operator)(*)来访问迭代器所指向的元素:
*iter = 0;
解引用操作符返回迭代器当前所指向的元素。假设 iter 指向 vector 对象 ivec 的第一元素,那么 *iter 和ivec[0] 就是指向同一个元素。上面这个语句的效果就是把这个元素的值赋为 0。迭代器使用自增操作符向前移动迭代器指向容器中下一个元素。从逻辑上说,C++迭代器的自增操作和int 型对象的自增操作类似。对 int 对象来说,操作结果就是把 int 型值“加 1”,而对迭代器对象则是把容器中的迭代器“向前移动一个位置”。因此,如果 iter 指向第一个元素,则 ++iter 指向第二个元素。由于 end 操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。
4示例程序:
a)例1,VS2010中的控台程序要Ctrl + F5 才能看到。
#include <iostream>
#include <vector>
using namespace std;int main()
{
//定义并赋值输出
vector<int> ivec;
cout<<"Befort *2 the elements are:"<<endl;
for(vector<int>::size_type ix=0;
ix!=10;++ix){ ivec.push_back(ix);
cout<<ivec[ix]<<'\t';
}
//把每个值乘以2并输出
cout<<endl<<"After *2 the elements are:"<<endl;
for(vector<int>::iterator iter=ivec.begin();
iter!=ivec.end();++iter)
{
*iter*=2; cout<<*iter<<'\t';
}
return 0;
}
b)例2
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> ivec;
ivec.push_back(1);
ivec.push_back(2);
ivec.push_back(3);
ivec.push_back(4);
for(vector<int>::iterator iter = ivec.begin();iter != ivec.end(); ++iter)
cout << *iter << endl;
return 0;
}
展开阅读全文