遍歷某些數據是我們經常遇到的問題, 下面簡單總結一下各種數據遍歷的方法:
(1)First,Next方法void FirstNextTest()
{
char string[] = "A string\tof ,,tokens\nand some more tokens";
char seps[] = " ,\t\n";
char *token;
token = strtok( string, seps );
while( token != NULL )
{
cout << token << endl;
token = strtok( NULL, seps );
}
cout << endl;
}
這種遍歷方式實際上就是有一個GetFirst方法,如果GetFirst成功, 接下來就可以不斷地GetNext遍歷。上面的 strtok( string, seps )實際上就是GetFirst, strtok( NULL, seps )實際上就是GetNext。
類似的還有Windows API,如 FindFirstFile, FindNextFile等。(2)Callback遍歷方法該方式通過讓我們在開始遍歷時設置一個callback函數, 當找到符合條件的數據時, 通過調用我們設置的callback把數據發回來。典型例子是Windows枚舉窗口的API: typedef BOOL (CALLBACK* WNDENUMPROC)(HWND, LPARAM);
BOOL EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam );(3)Index遍歷方法該方法通過暴露2個API來實現,GetCount和GetItemByIndex,前者返回總的數量,后者根據索引返回某個Item。我們通常實現的operator[](int nIndex)實際也是這種方法。(4)COM里IEnum方法IEnum接口包含4個方法:HRESULT Reset(); //重置到起始狀態HRESULT Next(ULONG celt, XXX* ppGet, ULONG* fetched); //嘗試去取celt個元素HRESULT Skip(ULONG celt); //跳過下面的celt個元素HRESULT Clone(IEnumXXX** ppEnum); //克隆一個當前狀態的Enum接口應該說IEnum接口對于我們的遍歷需求來說,它很完整也很強大。(5)C#里的IEnumerable和IEnumerator方法如果一個類支持枚舉,它會實現IEnumerable接口, IEnumerable接口就一個簡單的方法: IEnumerator GetEnumerator()IEnumerator接口包含3個方法:void Reset(); //重置Object Current(); //取得當前對象bool MoveNext(); //指向下一個對象,如果沒有下一個對象,返回False可以看到C#的接口和COM的IEnum接口其實很類似。(6)Iterator方法
這是STL的推薦方法, 我們知道Iterator在STL是容器和算法的粘合劑, 也是讓算法獨立于容器的隔離層。我們可以通過STL的begin(), end(), operator++實現上面枚舉方式的遍歷。仔細觀察我們會發現iterator是比上面enum方式更高層次的抽象, Iterator支持InputIterator, OutputIterator, ForwardIterator, BidirectionalIterator, RandomAccessIterator, 而上面的IEnum實際上只是ForwardIterator的一種實現。(7)C++11的foreach方法C++11的foreach本質上也是iterator的一種封裝, 只要你的類符下面的規范,它就能支持foreach:> 實現 begin()和end()方法> 返回的Iterator支持operator*, operator!=, operator++具體可以參考C++11 range-based for loops最后簡單總結下,如果沒有特殊情況, 在C++編程中個人還是推薦盡量用Iterator的方式,因為這種方式可以更好的和STL算法融合在一起。不知道大家還有沒有其他的遍歷方式?
posted on 2013-05-15 22:01
Richard Wei 閱讀(3868)
評論(0) 編輯 收藏 引用 所屬分類:
C++