嗨所以我對於迭代器有點迷茫,他們實際上是....在C++ STL瞭解迭代
在這種情況下即時通訊使用的名單,我不明白爲什麼你有什麼做一個迭代器:
std::list <int>::const_iterator iElementLocator;
由derefrence運營商dipslay列表的內容:
cout << *iElementLocator;
賦予它也許list.begin後();
請解釋什麼是一個迭代器,爲什麼我必須去除它/使用它!
謝謝!
嗨所以我對於迭代器有點迷茫,他們實際上是....在C++ STL瞭解迭代
在這種情況下即時通訊使用的名單,我不明白爲什麼你有什麼做一個迭代器:
std::list <int>::const_iterator iElementLocator;
由derefrence運營商dipslay列表的內容:
cout << *iElementLocator;
賦予它也許list.begin後();
請解釋什麼是一個迭代器,爲什麼我必須去除它/使用它!
謝謝!
有在STL三大基石:
在概念層次的容器保存數據。這本身並不是很有用,因爲你想做東西與數據;你想上運行,操縱它,查詢它,玩它。算法就是這樣做的。但算法不會保存數據,他們沒有數據 - 他們需要一個容器來完成這個任務。給容器一個算法,你有一個動作在進行。
要解決的唯一問題是,從技術角度來看,算法如何遍歷一個容器。從技術上講,一個容器可以是一個鏈表,也可以是一個數組,或二叉樹,或任何其他可以容納數據的數據結構。但遍歷一個數組的方式與遍歷二叉樹不同。儘管在概念上所有算法都需要從容器中一次「獲取」一個元素,然後處理該元素,但從容器中下一個元素的操作在技術上非常容器特定。
看起來好像您需要爲每個容器編寫相同的算法,以便每個版本的算法都具有正確的遍歷容器的代碼。但是有一個更好的解決方案:請容器返回一個可以遍歷容器的對象。該對象將有一個接口算法知道。當算法要求對象「獲取下一個元素」時,該對象將符合。由於對象直接來自容器,因此知道如何訪問容器的數據。並且由於該對象具有該算法知道的接口,所以我們不需要爲每個容器重複一個算法。
這是迭代器。
迭代器在這裏膠該算法的容器,沒有耦合的兩個。一個迭代器被耦合到一個容器,並且一個算法被耦合到迭代器的接口。這裏的魔法來源真的是模板編程。考慮標準copy()
算法:
template<class In, class Out>
Out copy(In first, In last, Out res)
{
while(first != last) {
*res = *first;
++first;
++res;
}
return res;
}
的copy()
算法作爲參數模板的類型In
和Out
類型的一個迭代兩個迭代。它將從位置first
開始並在位置last
之前結束的元素複製到res
中。算法知道獲得下一個元素需要說++first
或++res
。它知道要讀取一個元素,它需要說x = *first
並寫一個元素,它需要說*res = x
。這是接口算法假設和迭代器承諾的一部分。如果錯誤的迭代器不符合接口,那麼當類型未定義函數時,編譯器將通過類型In
或Out
發出調用函數的錯誤。
堆棧溢出問題經常成爲谷歌的熱門話題,此時回答說:「爲什麼不穀歌呢」看起來相當短視。 http://meta.stackexchange.com/questions/5280/embrace-the-non-googlers – 2011-04-09 18:39:20
我很懶。因此,我不會鍵入描述什麼是迭代器以及它們是如何使用的,尤其是當已經有很多在線文章可供您閱讀時。
這裏有一些,我可以引述一開始,proividing的鏈接來完成的文章:
MSDN說,
迭代器是 指針的推廣,從他們的 要求抽象一種允許C++程序以統一的方式與不同的 數據結構一起工作的方式。 迭代器充當容器和通用 算法之間的中介 。而不是在 特定數據類型上運行,算法是 定義爲在由迭代器類型指定的範圍 上操作。滿足迭代器的 要求的任何 數據結構然後可以由算法操作 。有 五種類型或 迭代器的類別[...]
順便說一句,似乎MSDN採取了文本加粗從C++標準本身,特別是從部分§24.1/ 1,它說:
迭代是 指針,其允許C++程序與以均勻的方式不同的數據結構 (容器) 工作的概括。爲了 能夠構建模板 算法正確 有效地工作在不同類型的數據 結構,圖書館正式確定不 只是接口也是 語義和複雜的假設迭代 。所有迭代器我支持 表達式* i,導致某個類,枚舉或 內置類型T的值爲 ,稱爲迭代器的值類型 。所有用於 的迭代器i其表達式(* i).m爲 ,定義明確,支持表達式 i-> m,其語義與 (* i).m相同。對於 的每個迭代類型X,定義了相等性,將有一個 對應的有符號整數類型 ,稱爲 迭代器的差異類型。
在C++中,一個迭代是任何對象 的是,指向一些元件在 範圍的元素(如數組或 的容器)的,有能力到 使用一組運算符(至少爲 ,增量(++)和 解除引用(*)運算符)遍歷該 範圍的元素。
迭代器的最明顯的形式是 指針[...]
而且你還可以閱讀這些:
請耐心等待並閱讀所有這些內容。希望你在C++中能夠知道迭代器是什麼。學習C++需要耐心和時間。
我建議閱讀關於在C++中的運算符重載。這將說明爲什麼*
和->
基本上可以表示任何事情。只有這樣你才能閱讀關於迭代器的內容。否則,它可能會顯得非常混亂。
迭代器是一個STL容器,指針指向一個數組。您可以將它們視爲STL容器的指針對象。作爲指針,您可以使用指針表示法(例如*iElementLocator
,iElementLocator++
)。作爲對象,他們將擁有自己的屬性和方法(http://www.cplusplus.com/reference/std/iterator)。
迭代器與容器本身不一樣。迭代器引用容器中的單個項目,並提供到達其他項目的方法。
考慮設計你自己的沒有迭代器的容器。它可以有一個size
函數來獲取它包含的項目數量,並且可以使[]
運算符超載,以允許您通過其位置獲取或設置項目。
但是這種「隨機存取」在某些種類的容器上不易實現。如果您獲得第百萬個項目:c[1000000]
並且容器在內部使用鏈接列表,則必須掃描一百萬個項目才能找到您想要的項目。
您可能決定允許集合記住「當前」項目。它可以像start
和more
和next
功能,讓您可以遍歷內容:
c.start();
while (c.more())
{
item_t item = c.next();
// use the item somehow
}
但是這使容器內的「迭代狀態」。這是一個嚴重的限制。如果您想將容器中的每件商品與其他商品進行比較,該怎麼辦?這需要兩個嵌套循環,遍歷所有項目。如果容器本身存儲迭代的位置,則無法嵌套兩個這樣的迭代 - 內部循環將會破壞外部循環的工作。
所以迭代器是一個迭代狀態的獨立副本。就可以開始迭代:
container_t::iterator i = c.begin();
即迭代器,i
,是一個獨立的對象,表示在容器內的位置。您可以獲取任何存儲在該位置:
item_t item = *i;
你可以移動到下一個項目:
i++;
有了一些迭代器,你可以跳過前幾個項目:
i += 1000;
或者獲取相對於迭代器標識的位置的某個位置的項目:
item_t item = i[1000];
並且有些迭代器可以向後移動。
,您可以通過迭代比較end
發現,如果你已經超過容器的內容達成:
while (i != c.end())
你能想到的end
爲返回,表示一個位置,是一個超越的迭代器容器中的最後一個位置。
使用迭代器(通常在C++中)要注意的一個重點是它們可能會失效。例如,如果您清空容器,通常會發生這種情況:指向該容器中位置的任何迭代器現在都變得無效。在那個狀態下,他們的大部分操作都是未定義的 - 任何事情都可能發生!
+1很好的解釋。 – Nawaz 2011-04-09 19:29:03