CMap
CMap 类别
语法 | 描述 |
---|---|
CMap::GetStartPosition |
传回第一个元素的位置。 |
CMap::GetNextAssoc |
取得下一个反覆运算的元素。 |
CMap::Lookup |
查阅对应至指定索引键的值。 |
CMap::RemoveKey |
移除由键指定的元素。 |
CMap::SetAt |
将元素插入到映射中;如果找到匹配的键,则替换现有元素。 |
举例如下:
1、定义一个CMAP,向这个CMAP中增加数据项(键-值对)。
|
|
2、遍历整个CMAP的常用方法。
|
|
3、在CMAP中查找相应的数据项。
|
|
完整例子
|
|
代码中,我已经给出了一些注释,我同样建议读者们,用英文在代码中注释,这样的好处实在是太多了。尤其在代码需要在不同编码的操作系统上调试的时候。
对于CMap这个类,我不得不着重啰嗦一下的是:遍历操作以及取下标【】操作,当然还有那个令很多人困惑不已的ARG_KEY到底应该如何选择的问题。
遍历,看注释#4,至于POSITION的含义,请在本空间,查看其它文章。先使用GetStartPosition()函数获得表头的位置,然后,我们可以使用GetNextAssoc函数来遍历。GetNextAssoc(POSITION& rNextPosition, KEY& rKey, VALUE& rValue)函数的参数值得说明一下,大家看到,3个参数都是引用,而第一个是rNextPosition,顾名思义,在函数返回之后,它将会指像下一个元组,当然这是在表还未遍历完的时候,否则,它将被置为空(NULL)。
【】,利用下标取元素的这个操作符,在CMap中被重载,用来返回指定Key值数据的引用,不过在注释#3处,对于先取"4th"这个Point的引用然后赋值的用法,看起来,似乎有点聪明过了头,因为在这之前,我们还没有插入"4th"所对应的元组,但是,程序却能正常的运行!为什么?其实,这样的用法是十分正确的,因为CMap毕竟不是数组,它是没有边界的,当CMap在获得一个它无法查询到的Key值的时候,它会将这个Key以及一个空的数据类型追加到Hash表中去,从而保证了上面的程序可以无误的运行。
我们已经说过,ARG_KEY是作为类型参数传入CMap的,但并不是任何类型都可以作为ARG_KEY传入的。为什么?看样子,这次不得不简单的说说Hash表的散列函数了。每个Hash表,总会使用一些散列函数,用来查找Key所对应的Value,理想状态下,我们当然希望Hash表,就是一个数组,虽然这不可能,不过这样理解,可以帮助我们更好的理解Hash表的物理结构,就让我们暂时把它看成一个数组吧。数组总是使用下标来直接获取元素的存储地址,而下标,显然应该是个非负整数,从而Hash表,也应该具备这样的特性,至少必须存在某种算法可以使传入的Key可以直接的转化为一个非负的整数,这也就是ARG_KEY的选择标准。从而对象、引用无论如何都不应该作为ARG_KEY成为CMap的类型参数,而int、unsigned int、指针以及地址就成为了ARG_KEY的常用类型参数,其实也就是那些类似于整型的数据类型。常常看到一些人在用CMap的时候,试图使用CString作为CMap中ARG_KEY的类型参数,这是应该被纠正的方向性错误,但有些人似乎会理直气壮的反驳我,因为他们发现类型参数KEY是可以使用CString的,这很奇怪吗?我说过KEY不能使用CString吗?之所以KEY可以使用CString而ARG_KEY却用的是LPCTSTR,那是因为CString重载了operator==(const char*)这个判等操作符,当CMap从Hash表中获得KEY之后,它会将ARG_KEY与KEY直接相比较。真正存于CMap内部的是KEY,也就是CString。这也就是为什么,我们经常会看到CMap被实化成CMap<CString, LPCTSTR/相当于const char,非Unicode情况下*/, CString,CString&>这样的一个四不像实化类的原因,至于CMap的效率优化问题,我们会在以后的文章中继续与大家探讨。
CMap的确是个很不错的数据结构,尤其在你建立一个字典的时候。比如idealsoft的含义是"曳光科技",这就是一个元组,也就是一个Pair,Key是"idealsoft",而Value是"曳光科技"。