关于std::Map容器的一点总结
来源:互联网 发布:网络电视的打开方式 编辑:程序博客网 时间:2024/06/07 16:05
Map容器的键值如果是C++内置数据类型,Map在构造底层的红黑树时会用到这些内置类型的<操作来进行元素间的比较操作。
但是当Map容器的键值不是内置类型而是自己定义的类型时,比如一个类、一个结构体。此时就要对Map的比较函数做一点处理,这种情况还会有两种情况出现:
第一种即为如果Map的键值是类的对象是,由于类模板是静态编译的,如果自己定义的Map键值没有实现 “<” 操作符,编译会出错。此时可以定义类的成员函数 bool operator < ( const NodeInfo& rValue )const(注意了这个const不能少)。这样在构造Map的红黑树及针对Map进行find操作时会自动调用到这个自己重载的“<”操作。
第二种情况即为如果Map的键值是类对象的指针时,由于编译器把指针当作32位的整数来处理,此时会存在潜在的错误:不管你自己定义的类中重载了“<”操作符与否,编译都会通过,因为它把指针当作32位整数来看待。但是在针对map进行find操作时不会找到自己想要的结果。此时必须实现自己的比较函数对象,不能再用Map默认的比较函数对象了,比如下面的比较函数对象:
class Compare : public std::binary_function<NodeInfo*,NodeInfo*,bool>
{
public:
bool operator()(const NodeInfo*plValue, constNodeInfo* rValue)
{
return plValue->addr.union_addr_mem.dwAddr < rValue->addr.union_addr_mem.dwAddr;
}
};
std::map<NodeInfo*,int,Compare> m_mapList;
这个map类的键值为 NodeInfo* ,值域为int,比较函数为Compare。
针对std::find()同std::find_if()的区别,它们的源码如下所示:
_InIt_Find(_InIt _First, _InIt _Last, const _Ty& _Val)
{ // find first matching_Val
_DEBUG_RANGE(_First, _Last);
for (; _First != _Last; ++_First)
if (*_First == _Val)
break;
return (_First);
}
_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying_Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
for (; _First != _Last; ++_First)
if (_Pred(*_First))
break;
return (_First);
}
Find()和find_if()都是到指定的容器中查找指定的元素。它们在比较元素相同时有不同之处,find()通过“==”操作符进行比较,find_if()则通过模板参数给定的比较函数对象进行比较。这就说明在你自己的类中要重载==操作符,如果你用find()的话,重载operator()操作符,如果你用find_if()的话。
如果容器中存的是对象的指针,想用find()函数来搜索容器中的元素,由于==号的左操作数不是这个类的对象,必须声明友元函数来比较它们(下面说明重载操作符在什么情况下使用友元,什么情况下使用类成员函数)。如下所示:
friend bool operator == ( const NodeInfo* plValue,const NodeInfo&rValue )
{
return plValue->addr.union_addr_mem.dwAddr == rValue.addr.union_addr_mem.dwAddr;
}
当使用find_if()进行操作时,则要根据容器中所存放的内容来定义operator() 操作符。例如:
bool operator () (const NodeInfo rValue )
{
return addr.union_addr_mem.dwAddr== rValue.addr.union_addr_mem.dwAddr;
}
bool operator () (const NodeInfo* rValue )
{
return addr.union_addr_mem.dwAddr== rValue->addr.union_addr_mem.dwAddr;
}
什么时候定义类成员操作符重载,什么时候定义非类成员操作符重载?
答:(1)如果一个重载操作符是类成员,那么只有当跟它一起使用的左操作数是该类对象时, 它才会被调用,如果该操作符的左操作数必须是其他类型,那么重载操作符必须是非类成员操作符重载。
(2)C++要求,赋值(=),下标 ([ ]),调用(())和成员访问箭头(->)操作符必须被指定为类成员操作符,否则错误。
- 关于std::Map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- STL中的map容器的一点总结
- std::map的用法总结
- std::map的用法总结
- std::map的用法总结
- TCL 之map容器的一点小结
- [C++/object c]_[初级]_[std::map容器的使用总结和NSDictionary词典使用总结]
- 关于 std::set/std::map 的几个为什么
- 关于 std::set/std::map 的几个为什么
- 关于 std::set/std::map 的几个为什么
- Weblogic学习笔记
- int VS smallint VS tinyint
- 将DataGrid内容生成标准的Excel格式文件
- Linux下的ds18b20驱动(运行环境 Fedora9.0 交叉编译 arm-linux-gcc-4.3.2 内核版本2.6.32)
- 写文章
- 关于std::Map容器的一点总结
- 中文乱码解决方案
- 怎样用office Word2003打开docx格式文档???
- 关于next_day的使用
- 推挽电路
- 不同排序规则数据库排序
- 网路命令
- Oracle建立自增主键
- PL/SQL Developer 8.* 系列注册码