遍历某些数据是我们经常遇到的问题, 下面简单总结一下各种数据遍历的方法:

(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 阅读(3824) 评论(0)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理