这是C++学习过程中,比较难理解抽象的知识,现在总结概括于此,望对大家有所帮助:
一般地当我们只想知道一个值是否存在时,set 最有用处;希望存储也可能修改一个相关的值时,map 最为有用.
首先要包含头文件
#include <map>
定义并生成map
为定义map对象我们至少要指明键和值的类型例如
map<string, int>
class employee;
map<int, employee*>
或者使用类型定义
typedef
MY_MAP
定义了map 以后下一步工作就是加入键/值元素对
方法一:
word_count[ string("Anna") ] = 1;
1一个未命名的临时string 对象被构造并传递给与map 类相关联的下标操作符,这个对象用Anna 初始化,
2 在word_count 中查找Anna 项,没有找到
3 一个新的键/值对被插入到word_count 中。当然键是一个string对象持有“Anna”。但是值不是1 而是0
4 插入完成接着值被赋为1
用下标操作符把map 初始化至一组元素集合,会使每个值都被初始化为缺省值。然后再被赋值为显式的值,如果元素是类对象而且它的缺省初始化和赋值的运算量都很大。就会影响程序的性能
方法二:
word_count.insert(map<string,int>::value_type( string("Anna"), 1 ));
其作用是创建一个pair对象,接着将其直接插入map
typedef
word_count.insert( valType( string("Anna"), 1 ));
方法三:
my_Map.insert(pair <string,int> ( "c ",3));
方法四:
my_Map.insert(make_pair( "d ",4));
方法五:
为插入一定范围内的键/值元素,我们可以用另一个版本的insert()方法。它用一对iterator作为参数。
map< string, int > word_count;
// ... fill it up
map< string, int > word_count_two;
// 插入所有键/值对
word_count_two.insert(word_count.begin(),word_count.end());
查找并获取map 中的元素。
下标操作符给出了获取一个值的最简单方法例如
// map<string,int> word_count;
int count = word_count[ "wrinkles" ];
但是只有当map 中存在这样一个键的实例时该代码才会表现正常如果不存在这样的实例使用下标操作符会引起插入一个实例在本例中键/值对
string( "wrinkles" ), 0
被插入到word_count 中count 被初始化为0
有两个map 操作能够发现一个键元素是否存在而且在键元素不存在时也不会引起插入实例
1
count()返回map 中keyValue 出现的次数当然对于map
而言返回值只能是0 或1 如果返回值非0 我们就可以安全地使用下标操作符例如
int count = 0;
if ( word_count.count( "wrinkles" ))
count = word_count[ "wrinkles" ];
2
如果实例存在则find()返回指向该实例的iterator 如果不存在则返回等于end()的iterator 例如
int count = 0;
map<string,int>::iterator it = word_count.find( "wrinkles" );
if ( it != word_count.end() )
count = (*it).second;
指向map中元素的iterator指向一个pair对象(下文有对pair的介绍)其中first拥有键,second拥有值
对map 进行迭代
我们可以通过对由begin()和end()两个迭代器标记的所有元素进行迭代来做到这一点。
typedef map<string,int> tmap;
tmap::iterator iter = text_map->begin(),
iter_end = text_map->end();
while ( iter != iter_end )
{ cout << "word: " << (*iter).first << " ("<<(*iter).second<<")";
对map中的元素进行删除
从map 中删除元素的erase()操作有三种变化形式。
为了删除一个独立的元素我们传递给erase()一个键值或iterator(删除的是当前迭代到的那个元素), 为了删除一列元素我们传递给erase()一对lieator。
一个map 只能拥有一个键值的惟一实例,为了给同一个键提供多个项我们必须使用multimap。
对map的其他操作
my_Map.size()
my_Map.empty()
my_Map.clear()
PS:一些问题解惑:
Q:以下两种定义方式,在进行map.clear()的时候,内存释放上有啥不同?
A:
小结:
Q:
A:
Q:
A:
class CFileAttribute
{
};
那么memcpy没什么不妥。但假若你的CFileAttribute中包含(或者嵌套包含)指针,那么就可能有问题了,因为指针的复制并不等于内存块的复制,因此你必须显示地提供一个CFileAttribute::operator=,并且在其中把指针所对应的内存块也复制一遍,这才是真正的副本(此时这两个副本内的指针反而是不相等的,因为分别指向不同的内存块),其中任何一个副本的销毁(一般会在析构函数中把其指针所指向的内存块同时销毁)都不会影响到另一个副本的独立存在,既采用的是深拷贝(详解参看深拷贝与浅拷贝)。
你的CFileAttribute::m_str显然是CString类型,而CString内部当然是一个指针,因此缺省的、memcpy方式的拷贝构造函数以及赋值操作符一定会出问题。你必须显式提供自己的拷贝构造函数以及赋值操作符。
PS:我在使用map模板类时碰到的一个问题:
使用map时vc6居然跳出了上百个warning C4786,上网查找才知道这个是vc的bug,由于stl里用的字符串过长,vc搞不定,呵呵,虽然可以不去管,但是如果程序出错误,要在上百条的warning找到错误信息还是很困难的。有人说用#pragma warning(disable: 4786)可以去掉,但是实验了一下居然不行,后来发现一个老外说要把这句话放到所有stl头的include之前,于是照办,果然可以,^_^老外就是敬业~~
**************************************************************************************
pair
pair同 map、set、mulitmap、multiset一样是关联容器
1 pair的应用
pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。
std::pair模型
template
2 make_pair函数
template pair make_pair(T1 a, T2 b) { return pair(a, b); }
很明显,我们可以使用pair的构造函数也可以使用make_pair来生成我们需要的pair。一般make_pair都使用在需要pair做参数的位置,可以直接调用make_pair生成pair对象很方便,代码也很清晰。另一个使用的方面就是pair可以接受隐式的类型转换,这样可以获得更高的灵活度。灵活度也带来了一些问题如:
std::pair<int, float>(1, 1.1);
std::make_pair(1, 1.1);
是不同的,第一个就是float,而第2个会自己匹配成double。
这是C++学习过程中,比较难理解抽象的知识,现在总结概括于此,望对大家有所帮助:
一般地当我们只想知道一个值是否存在时,set 最有用处;希望存储也可能修改一个相关的值时,map 最为有用.
首先要包含头文件
#include <map>
定义并生成map
为定义map对象我们至少要指明键和值的类型例如
map<string, int>
class employee;
map<int, employee*>
或者使用类型定义
typedef
MY_MAP
定义了map 以后下一步工作就是加入键/值元素对
方法一:
word_count[ string("Anna") ] = 1;
1一个未命名的临时string 对象被构造并传递给与map 类相关联的下标操作符,这个对象用Anna 初始化,
2 在word_count 中查找Anna 项,没有找到
3 一个新的键/值对被插入到word_count 中。当然键是一个string对象持有“Anna”。但是值不是1 而是0
4 插入完成接着值被赋为1
用下标操作符把map 初始化至一组元素集合,会使每个值都被初始化为缺省值。然后再被赋值为显式的值,如果元素是类对象而且它的缺省初始化和赋值的运算量都很大。就会影响程序的性能
方法二:
word_count.insert(map<string,int>::value_type( string("Anna"), 1 ));
其作用是创建一个pair对象,接着将其直接插入map
typedef
word_count.insert( valType( string("Anna"), 1 ));
方法三:
my_Map.insert(pair <string,int> ( "c ",3));
方法四:
my_Map.insert(make_pair( "d ",4));
方法五:
为插入一定范围内的键/值元素,我们可以用另一个版本的insert()方法。它用一对iterator作为参数。
map< string, int > word_count;
// ... fill it up
map< string, int > word_count_two;
// 插入所有键/值对
word_count_two.insert(word_count.begin(),word_count.end());
查找并获取map 中的元素。
下标操作符给出了获取一个值的最简单方法例如
// map<string,int> word_count;
int count = word_count[ "wrinkles" ];
但是只有当map 中存在这样一个键的实例时该代码才会表现正常如果不存在这样的实例使用下标操作符会引起插入一个实例在本例中键/值对
string( "wrinkles" ), 0
被插入到word_count 中count 被初始化为0
有两个map 操作能够发现一个键元素是否存在而且在键元素不存在时也不会引起插入实例
1
count()返回map 中keyValue 出现的次数当然对于map
而言返回值只能是0 或1 如果返回值非0 我们就可以安全地使用下标操作符例如
int count = 0;
if ( word_count.count( "wrinkles" ))
count = word_count[ "wrinkles" ];
2
如果实例存在则find()返回指向该实例的iterator 如果不存在则返回等于end()的iterator 例如
int count = 0;
map<string,int>::iterator it = word_count.find( "wrinkles" );
if ( it != word_count.end() )
count = (*it).second;
指向map中元素的iterator指向一个pair对象(下文有对pair的介绍)其中first拥有键,second拥有值
对map 进行迭代
我们可以通过对由begin()和end()两个迭代器标记的所有元素进行迭代来做到这一点。
typedef map<string,int> tmap;
tmap::iterator iter = text_map->begin(),
iter_end = text_map->end();
while ( iter != iter_end )
{ cout << "word: " << (*iter).first << " ("<<(*iter).second<<")";
对map中的元素进行删除
从map 中删除元素的erase()操作有三种变化形式。
为了删除一个独立的元素我们传递给erase()一个键值或iterator(删除的是当前迭代到的那个元素), 为了删除一列元素我们传递给erase()一对lieator。
一个map 只能拥有一个键值的惟一实例,为了给同一个键提供多个项我们必须使用multimap。
对map的其他操作
my_Map.size()
my_Map.empty()
my_Map.clear()
PS:一些问题解惑:
Q:以下两种定义方式,在进行map.clear()的时候,内存释放上有啥不同?
A:
小结:
Q:
A:
Q:
A:
class CFileAttribute
{
};
那么memcpy没什么不妥。但假若你的CFileAttribute中包含(或者嵌套包含)指针,那么就可能有问题了,因为指针的复制并不等于内存块的复制,因此你必须显示地提供一个CFileAttribute::operator=,并且在其中把指针所对应的内存块也复制一遍,这才是真正的副本(此时这两个副本内的指针反而是不相等的,因为分别指向不同的内存块),其中任何一个副本的销毁(一般会在析构函数中把其指针所指向的内存块同时销毁)都不会影响到另一个副本的独立存在,既采用的是深拷贝(详解参看深拷贝与浅拷贝)。
你的CFileAttribute::m_str显然是CString类型,而CString内部当然是一个指针,因此缺省的、memcpy方式的拷贝构造函数以及赋值操作符一定会出问题。你必须显式提供自己的拷贝构造函数以及赋值操作符。
PS:我在使用map模板类时碰到的一个问题:
使用map时vc6居然跳出了上百个warning C4786,上网查找才知道这个是vc的bug,由于stl里用的字符串过长,vc搞不定,呵呵,虽然可以不去管,但是如果程序出错误,要在上百条的warning找到错误信息还是很困难的。有人说用#pragma warning(disable: 4786)可以去掉,但是实验了一下居然不行,后来发现一个老外说要把这句话放到所有stl头的include之前,于是照办,果然可以,^_^老外就是敬业~~
**************************************************************************************
pair
pair同 map、set、mulitmap、multiset一样是关联容器
1 pair的应用
pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。
std::pair模型
template
2 make_pair函数
template pair make_pair(T1 a, T2 b) { return pair(a, b); }
很明显,我们可以使用pair的构造函数也可以使用make_pair来生成我们需要的pair。一般make_pair都使用在需要pair做参数的位置,可以直接调用make_pair生成pair对象很方便,代码也很清晰。另一个使用的方面就是pair可以接受隐式的类型转换,这样可以获得更高的灵活度。灵活度也带来了一些问题如:
std::pair<int, float>(1, 1.1);
std::make_pair(1, 1.1);
是不同的,第一个就是float,而第2个会自己匹配成double。