STL是标准C++系统的一组模板类,使用STL模板类最大的好处就是在各种C++编译器上都通用。
在STL模板类中,用于线性数据存储管理的类主要有vector, list, map 等等。本文主要针对map对象,结合自己学习该对象的过程,讲解一下具体用法。本人初学,水平有限,讲解差错之处,请大家多多批评指正。
map对象所实现的功能跟MFC得CMap相似,但是根据一些文章的介绍和论述,MFC CMap在个方面都与STL map有一定的差距,例如不是C++标准,不支持赋值构造,对象化概念不清晰等等。
使用map对象首先要包括头文件,包含语句中必须加入如下包含声明
#include <map>
注意,STL头文件没有扩展名.h
包括头文件后就可以定义和使用map对象了,map对象是模板类,需要关键字和存储对象两个模板参数,例如:
std:map<int, CString> enumMap;
这样就定义了一个用int作为关键字检索CString条目的map对象,std表示命名空间,map对象在std名字空间中,为了方便,在这里我仍然使用了CString类,其实应该使用标准C++的std::string类,我们对模板类进行一下类型定义,这样用的方便,当然,不定义也可以,代码如下:
typedef std:map<int, CString> UDT_MAP_INT_CSTRING;
UDT_MAP_INT_CSTRING enumMap;
UDT_MAP_INT_CSTRING enumMap;
如此map对象就定义好了,增加,改变map中的条目非常简单,因为map类已经对[]操作符进行了重载,代码如下:
enumMap[1] = "One";
enumMap[2] = "Two";
.....
enumMap[1] = "One Edit";
enumMap[2] = "Two";
.....
enumMap[1] = "One Edit";
或者insert方法
enumMap.insert(make_pair(1,"One"));
返回map中目前存储条目的总数用size()方法:
int nSize = enumMap.size();
查找map中是否包含某个关键字条目用find方法,传入的参数是要查找的key,在我们的例子里,是一个int数据,map中的条目数据是顺序存储的,被称作为一个sequence,在这里需要提到的是begin()和end()两个成员,分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator,iterator被定义为map中条目的类型,查找是否包含某个条目的代码如下:
int nFindKey = 2; //要查找的Key
UDT_MAP_INT_CSTRING::iterator it; //定义一个条目变量(实际是指针)
it = enumMap.find(nFindKey);
if(it == enumMap.end()) {
//没找到
}
else {
//找到
}
UDT_MAP_INT_CSTRING::iterator it; //定义一个条目变量(实际是指针)
it = enumMap.find(nFindKey);
if(it == enumMap.end()) {
//没找到
}
else {
//找到
}
//find的时候注意key的数据类型,最好用CString之类的能消除数据类型差异的key,否则可能会出现强制转换后仍找不到的情况。
需要说明的是iterator, begin(), end()是STL模板类的一个通用概念,操作方法也大同小异
通过map对象的方法获取的iterator数据类型是一个std::pair对象,包括两个数据 iterator.first 和 iterator.second 分别代表关键字和存储的数据
移除某个条目用erase() 该成员方法的定义如下
iterator erase(iterator it);
iterator erase(iterator first, iterator last);
size_type erase(const Key& key);
iterator erase(iterator first, iterator last);
size_type erase(const Key& key);
分析一下这三个重载方法定义,大家不用说也能看明白一点点了吧,第一个通过一个条目对象删除,这个对象可以从find之类的方法获得,第二个定义删除一个范围,需要一个起始条目和一个终止条目,第三个通过关键字删除,这个与我们的想法和习惯最接近,代码例子如下:
enumMap.erase(1); //删掉关键字“1”对应的条目
enumMap.erase(enumMap.begin()); //删掉第一个条目
enumMap.erase(enumMap.begin(), enumMap.begin() + 1); //删掉起始的两个条目
enumMap.erase(enumMap.begin()); //删掉第一个条目
enumMap.erase(enumMap.begin(), enumMap.begin() + 1); //删掉起始的两个条目
呵呵,增删改查都说完了,相信读过本文,map对象也应该会使用了,这些是我1个多星期来钻研的结果,拿出来与大家分享。
最后,还有一个clear(),不用问,全删的时候就不要一个一个erase了,clear()就相当于enumMap.erase(enumMap.begin(), enumMap.end());
map的遍历:
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
map<string,int> m;
m["a"]=1;
m["b"]=2;
m["c"]=3;
map<string,int>::iterator it;
for(it=m.begin();it!=m.end();++it)
cout<<"key: "<<it->first <<" value: "<<it->second<<endl;
return 0;
}
#include<string>
#include<iostream>
using namespace std;
int main()
{
map<string,int> m;
m["a"]=1;
m["b"]=2;
m["c"]=3;
map<string,int>::iterator it;
for(it=m.begin();it!=m.end();++it)
cout<<"key: "<<it->first <<" value: "<<it->second<<endl;
return 0;
}
map<string,int>::iterator it; 定义一个迭代指针it。
it->first 为索引键值,it->second 为值。
在对象中应用时,最好在析构函数中要调用它的clear方法,
例如class a{
map<int,int> m;
~a(){
m.clear();
}
}