写篇文章不容易,希望大家珍惜作者的劳动成果,转载请注明出处^^
原文地址:http://blog.csdn.net/gongxinheng/archive/2010/03/27/5421914.aspx
by: HengStar
2010/3/27
我是一名游戏开发程序员,研究C++ Boost库已经有一小段时日了,学的越多愈发愈感觉出它的强大,每次学习后在实战项目中高效地使用,都让我兴奋不已,为了让自己记忆更深刻,同时也希望越来越多的同行们能快速高质量地解决实际项目中遇到的各种问题,在此将我将自己实战中实用boost的经验分享给大家,本人才疏学浅,如果有什么问题希望读者们能帮助指出,大家共同探讨^_^
本章介绍的主题是multi_index_container
注:继续往下读之前希望你对C++模板和stl的一些知识有过了解
什么是多索引容器?为什么要使用它?如何使用?
接下来一一回答以上的问题。
想必大家在实际开发中一定多多少少会遇到以下的问题,我需要创建一个map,并且需要两种方式去索引,比如:创建一个<学号,姓名>的map,但是我既需要用学号去索引,又需要用姓名去索引,但std::map只能用它的key_type(在这里是学号)作为索引进行查找操作,该怎么办呢?“这有何难”?有人可能想到了,用value_type(姓名)索引也是可以的嘛,大不了写一个函数去遍历这个map,然后把要查找的姓名跟每个pair的second比较一下,如果相等不就找到了么?OK,没错,这样可以解决问题,但仅仅只是很粗糙地解决问题,如果这个map很大,每次查找都要遍历一遍,查找平均复杂度为O(n/2),如果你在需要高效的商业项目上使用,相信到性能测试的那天就是你收拾包袱走人的时刻了...just a joke^^让我们来讨论一些高效点的方法吧,仍然使用标准库的std::map,这次我们创建两个,一个使用<学号,姓名>,另一个则是<姓名,学号>,在每加入一个学生的时候都需要在两个map中各插入一个元素,移除的时候亦是,这种方法比最初的方法要好一些了,至少它可以做到高效的双向查找,但是仍然还是有缺陷的,比如说维护起来很麻烦,每次操作时都需要同时关照两个map的对应关系,一旦忽略了一些细节导致其中一个出了一点差错,可能就会酿成大错。
对于这种简单的需要双向查找的容器,使用boost::bimap就可以方便的解决问题,boost::bimap就是专为这种情况设计的容器,当然它的强大可能超出了你的想象,但是这里我们讨论的不是它,我们在实际开发中遇到的情况往往更复杂,比如说要创建一个<学号,学生信息>(学生信息是一个结构)的map,用前面的方法就得稍稍麻烦一点,比如重载学生信息结构的operator==来进行索引的依据,这些吃亏不讨好的方法我在这里就不再重复讨论了,让我们进入本章的正题,使用multi_index_container,没错,它可以轻松的帮你解决如上的所有问题,Let's go!
让我们先创建一些结构
以上的代码只是一些结构定义,比较简单,这里不再多介绍,唯一CreateStudent需要说明一下,由于学号是唯一不能重复的,所以创建学生时需要统一管理,构造函数声明为私有的是不让用户直接构造这个类,而只能通过CreateStudent函数去创建,这个CreateStudent函数就是一个简单的工厂生产函数,了解设计模式-工厂模式的读者一定很熟悉了,我们的目标是把学号、姓名、年龄同时作为索引,接下来引入我们的主角
解释一下上述代码,由于模板元是比较复杂的东东,要深入会更晕,这里只是简单介绍用法,所以不会剖析细节。首先是三个struct,这是给予需要创建索引的变量的标签&