遍历某些数据是我们经常遇到的问题, 下面简单总结一下各种数据遍历的方法:
(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 阅读(3832)
评论(0) 编辑 收藏 引用 所属分类:
C++