一淑际、迭代器
迭代器提供對(duì)一個(gè)容器中的對(duì)象的訪問(wèn)方法,并且定義了容器中對(duì)象的范圍扇住。迭代器就如同一個(gè)指針春缕。事實(shí)上,C++的指針也是一種迭代器艘蹋。但是锄贼,迭代器不僅僅是指針,因此你不能認(rèn)為他們一定具有地址值女阀。例如宅荤,一個(gè)數(shù)組索引屑迂,也可以認(rèn)為是一種迭代器。
迭代器有各種不同的創(chuàng)建方法冯键。程序可能把迭代器作為一個(gè)變量創(chuàng)建惹盼。一個(gè)STL容器類可能為了使用一個(gè)特定類型的數(shù)據(jù)而創(chuàng)建一個(gè)迭代器。作為指針琼了,必須能夠使用*操作符類獲取數(shù)據(jù)逻锐。你還可以使用其他數(shù)學(xué)操作符如++。典型的雕薪,++操作符用來(lái)遞增迭代器昧诱,以訪問(wèn)容器中的下一個(gè)對(duì)象。如果迭代器到達(dá)了容器中的最后一個(gè)元素的后面所袁,則迭代器變成past-the-end值盏档。使用一個(gè)past-the-end值得指針來(lái)訪問(wèn)對(duì)象是非法的,就好像使用NULL或?yàn)槌跏蓟闹羔樢粯印?/p>
提示
STL不保證可以從另一個(gè)迭代器來(lái)抵達(dá)一個(gè)迭代器燥爷。例如蜈亩,當(dāng)對(duì)一個(gè)集合中的對(duì)象排序時(shí),如果你在不同的結(jié)構(gòu)中指定了兩個(gè)迭代器前翎,第二個(gè)迭代器無(wú)法從第一個(gè)迭代器抵達(dá)稚配,此時(shí)程序注定要失敗。這是STL靈活性的一個(gè)代價(jià)港华。STL不保證檢測(cè)毫無(wú)道理的錯(cuò)誤道川。
二、迭代器類型
STL定義了5種迭代器立宜,并根據(jù)所需的迭代器類型對(duì)算法進(jìn)行了描述冒萄。對(duì)于這5種迭代器,都可以執(zhí)行解除引用操作(即為它們定義了運(yùn)算符)橙数,也可進(jìn)行比較尊流,看其是相等(使用==運(yùn)算符,可能被重載了)還是不相等(使用!=運(yùn)算符灯帮,可能被重載了)崖技。如果兩個(gè)迭代器相同,則對(duì)它們執(zhí)行解除引用操作得到的值將相同钟哥。
2.1 輸入迭代器
- 提供對(duì)數(shù)據(jù)的只讀訪問(wèn)迎献,不允許修改容器中的值。
- 單通行瞪醋,可以遞增,但不能倒退装诡。
2.2 輸出迭代器
- 提供對(duì)數(shù)據(jù)的只寫訪問(wèn)银受,不允許讀取容器中的值践盼。
- 單通行。
2.3 正向迭代器
- 提供對(duì)數(shù)據(jù)的讀寫操作宾巍,也可以只讀咕幻。
- 固定和可重復(fù)排序。
- 單通行顶霞。
2.4 雙向迭代器
- 具有正向迭代器的所有特性肄程。
- 同時(shí)支持兩種(前綴和后綴)遞減運(yùn)算符。
2.5 隨機(jī)訪問(wèn)迭代器
- 具有雙向迭代器的所有特性
- 同時(shí)添加了支持隨機(jī)訪問(wèn)的操作(如指針增加運(yùn)算)选浑。
三蓝厌、指針迭代器
正如下面的小程序顯示的,一個(gè)指針也是一種迭代器古徒。該程序同樣顯示了STL的一個(gè)主要特性——它不只是能夠用于它自己的類類型拓提,而且也能用于任何C或C++類型。Listing 1.iterdemo.cpp, 顯示了如何把指針作為迭代器用于STL的find()算法來(lái)搜索普通的數(shù)組隧膘。
Listing 1. iterdemo.cpp
#include <iostream.h>
#include <algorithm>
using namespace std;
#define SIZE 100
int iarray[SIZE];
int main()
{
iarray[20] = 50;
int* ip = find(iarray, iarray + SIZE, 50);
if (ip == iarray + SIZE)
cout << "50 not found in array" << endl;
else
cout << *ip << " found in array" << endl;
return 0;
}
在引用了I/O流庫(kù)和STL算法頭文件(注意沒(méi)有.h后綴)代态,該程序告訴編譯器使用std名字空間。使用std名字空間的這行是可選的疹吃,因?yàn)榭梢詣h除該行對(duì)于這么一個(gè)小程序來(lái)說(shuō)不會(huì)導(dǎo)致名字沖突蹦疑。
程序中定義了尺寸為SIZE的全局?jǐn)?shù)組。由于是全局變量萨驶,所以運(yùn)行時(shí)數(shù)組自動(dòng)初始化為零歉摧。下面的語(yǔ)句將在索引20位置處地元素設(shè)置為50,并使用find()算法來(lái)搜索值50:
iarray[20] = 50;
int* ip = find(iarray, iarray + SIZE, 50);
find()函數(shù)接受三個(gè)參數(shù)。頭兩個(gè)定義了搜索的范圍篡撵。由于C和C++數(shù)組等同于指針判莉,表達(dá)式iarray指向數(shù)組的第一個(gè)元素。而第二個(gè)參數(shù)iarray + SIZE等同于past-the-end 值育谬,也就是數(shù)組中最后一個(gè)元素的后面位置券盅。第三個(gè)參數(shù)是待定位的值,也就是50膛檀。find()函數(shù)返回和前兩個(gè)參數(shù)相同類型的迭代器锰镀,這兒是一個(gè)指向整數(shù)的指針ip。
提示
必須記住STL使用模板咖刃。因此泳炉,STL函數(shù)自動(dòng)根據(jù)它們使用的數(shù)據(jù)類型來(lái)構(gòu)造。
為了判斷find()是否成功嚎杨,例子中測(cè)試ip和 past-the-end 值是否相等:
if (ip == iarray + SIZE) ...
如果表達(dá)式為真花鹅,則表示在搜索的范圍內(nèi)沒(méi)有指定的值。否則就是指向一個(gè)合法對(duì)象的指針枫浙,這時(shí)可以用下面的語(yǔ)句顯示:
cout << *ip << " found in array" << endl;
測(cè)試函數(shù)返回值和NULL是否相等是不正確的刨肃。不要像下面這樣使用:
int* ip = find(iarray, iarray + SIZE, 50);
if (ip != NULL) ... // ??? incorrect
當(dāng)使用STL函數(shù)時(shí)古拴,只能測(cè)試ip是否和past-the-end 值是否相等。盡管在本例中ip是一個(gè)C++指針,其用法也必須符合STL迭代器的規(guī)則真友。
四黄痪、容器迭代器
盡管C++指針也是迭代器,但用的更多的是容器迭代器盔然。容器迭代器用法和iterdemo.cpp一樣桅打,但和將迭代器申明為指針變量不同的是,你可以使用容器類方法來(lái)獲取迭代器對(duì)象愈案。兩個(gè)典型的容器類方法是begin()和end()挺尾。它們?cè)诖蠖鄶?shù)容器中表示整個(gè)容器范圍。其他一些容器還使用rbegin()和rend()方法提供反向迭代器刻帚,以按反向順序指定對(duì)象范圍潦嘶。
下面的程序創(chuàng)建了一個(gè)矢量容器(STL的和數(shù)組等價(jià)的對(duì)象),并使用迭代器在其中搜索崇众。該程序和前一章中的程序相同掂僵。
Listing 2. vectdemo.cpp
#include <iostream.h>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> intVector(100);
void main()
{
intVector[20] = 50;
vector<int>::iterator intIter =
find(intVector.begin(), intVector.end(), 50);
if (intIter != intVector.end())
cout << "Vector contains value " << *intIter << endl;
else
cout << "Vector does not contain 50" << endl;
}
注意用下面的方法顯示搜索到的數(shù)據(jù):
cout << "Vector contains value " << *intIter << endl;
? 由 Leung 寫于 2018 年 9 月 7 日