C++Primer——迭代器iterator
迭代器是一种检查容器内元素并遍历元素的数据类型。
所有的标准库容器都定义了相应的迭代器类型,而只有少数容器支持下标操作。
例如:
vector<int> :: iterator iter;
定义了一个名为 iter 的变量,它的类型是由 vector<int> 定义的 iterator 类型。每个标准库容器类型都定义了一个 iterator 成员,这里的 iterator 与迭代器实际类型的含义相同。
/*
听起来太晦涩了,也是自己水平不够,不过,我的理解就是,迭代器就是升级了的元素指针,以前的指针只用来加加减减访问元素,而这里被规范化,拥有了自己独立的包装,对外也提供了操作接口(迭代器的一些操作begin/end 之类)。而且,还有一层意思就是,凡是实现了这样的操作功能的东西都可以称作迭代器。
*/
迭代器的操作:
赋值:
vector<int> :: iterator iter = ivec.begin( );
迭代器 iter 初始化为由明 begin 的 vector 操作返回的值,假设 vector 不空,初始化后, iter 即指该元素为 ivec[0]。
由 end 操作返回的迭代器指向 vector 的“末端元素的下一个”( off-the-end iterator ),表明它指向了一个不存在的元素。
自增:
迭代器可以自增操作以从容器中的一个元素移动到另一个元素。
解引用操作:
*iter 返回迭代器当前所指向的元素(这里叫做解引用操作符)。
由于 end 操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。
比较操作:
== 或 != , 如果两个迭代器对象指向同一个元素,则它们相等。
const_iterator 类型,只能用于读取容器内的元素,但不能改变其值。
当对普通 iterator 解引用的时候,得到某个元素的非 const 引用。而对 const_iterator 类型解引用的时候,则可以得到一个指向 const 对象的引用,是一个 const 值,不允许重写。
vector<int> :: const_iterator iter = ivec.begin( );
const vector<int> :: iterator iter = ivec.begin( ); const 的 iterator 对象:
/*
这两个的区别就是, const_iterator 自身不是 const 的,但要求把它指向的元素当作 const 类型来对待,不管原来的元素是不是 const ,总之是只读不写。
而 const 的 iterator 自身是 const ,但不要求其指向的元素是 const ,所以它只能指向非 const 元素,而且只能指向某一个元素而不能再指向其他元素。——基本没什么用。
*/
警告:
任何改变 vector 长度的操作都会使已存在的迭代器失效。例如在调用 push_back 之后,就不能再信赖指向vector 的迭代器的值了。(可能是因为,长度改变之后, vector 的存储位置可能改变的原因吧,那么重新为迭代器赋值之后,还能接着用么?)
一个小问题:
计算 mid 迭代器:
OK:
vector<int>::iterator mid = vi.begin() + vi.size() / 2;
ERROR:
Vector<int>::iterator mid = ( vi.begin() + vi.end() ) / 2;
原因:两个迭代器相加的操作是未定义的。
理论:
迭代器的算术操作:
除了一次移动迭代器的一个元素的增量操作符外, vector (其他标准库容器迭代器很少)也支持其他的算术操作。这些操作称为迭代器算术操作( iterator arithmetic ),包括:
iter + n
iter – n
iter1 – iter2 计算两个迭代器对象的距离,该距离是名为 difference_type 的 signed 类型的值它与 size_type 类似,也是由 vector 定义的。 iter1 和 iter2 必须指向同一 vector ,或者指向 vector 末端之后的下一个元素。
也就是说,看似象个指针,但是操作起来是没有那么随便的!!!