基于C++ map中key使用指针问题的详解
C++实际开发的过程会经常使用到map。map是一个key-value值对,key唯一,可以用find进行快速的查找。其时间复杂度为O(logN),如果采用for循环进行遍历数据时间复杂度为O(N)。如果map中的数据量比较少时,采用find和for循环遍历的效率基本没有太大的区别,但是在实际的开发过程中,存储在map中的数据往往是大量的,这个时候map采用find方式效率比遍历效率高的多。
确定采用find方式查找数据后,我们需要考虑存储map的空间复杂度,对于基础数据类型的数据(int char等)这里就不做讨论。本文讨论的是map中存储的数据结构struct情况。
1、如果map中的key为struct此时,需要先对struct进行操作符重载,关于这部分内容可以参考C++ 重载操作符示例
2、map中的key只能是对象,而不能是指针。(这一点尤为重要)。
下面给出三个map定义进行说明:
std::map<NHSymbolkey, Stru_NHSymbol>* pmapNHSymbolInfo1
std::map<NHSymbolkey, Stru_NHSymbol*>* pmapNHSymbolInfo2
std::map<NHSymbolkey*, Stru_NHSymbol*>* pmapNHSymbolInfo2
其中,pmapNHSymbolInfo1、pmapNHSymbolInfo2中使用find正常,遍历也正常,pmapNHSymbolInfo3使用find查找不到对应的数据(数据已经存在,find不到,遍历可以找到)
原因:std::map<NHSymbolkey*, Stru_NHSymbol*>* pmapNHSymbolInfo2在find的时候是根据指针进行查找的。而在数据insert时,数据都是new的,每次new出的地址是不一样的,在find数据时,根据地址查找结果就找不到数据。通过遍历是取出地址中内容一一比较,这样能够找到数据。
pmapNHSymbolInfo1、pmapNHSymbolInfo2两种方式都可以使用find方式查找数据,但是pmapNHSymbolInfo1中Stru_NHSymbol为对象,这样会使map占用空间比较大,pmapNHSymbolInfo2的Stru_NHSymbol为指针,存储时地址占用空间小,但是每次都是new处理来的,所有一定要记住使用完成后一定要delete,否则会出现内存泄露。
3、map插入数据2中方式比较
std::map<NHSymbolkey, Stru_NHSymbol*>* pmapNHSymbolInfo
pmapNHSymbolInfo->insert(std::make_pair(pNHSymbolkey, pNHSymbol));该方式的key如果出现重复,则会插入数据失败;
(*pmapNHSymbolInfo)[objNHSymbolkey] = pNHSymbol;该方式的key如果出现重复则直接覆盖掉原来的数据,永远不会出现插入失败的问题。
结论:C++ map中key不要使用指针,请直接使用对象。
相关推荐
-
C++中 map的基本操作
1.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 2.map的功能 自动建立Key - value的对应.key 和 value可以是任意你需要的类型. 根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次. 快速插入Key - Value 记录. 快速删除记录 根据Key 修改val
-
VC++中图像处理类CBitmap的用法
VC++中图像处理类CBitmap的用法 class CBitmap : public CGdiObject { DECLARE_DYNAMIC(CBitmap) public: static CBitmap* PASCAL FromHandle(HBITMAP hBitmap); // Constructors CBitmap(); BOOL LoadBitmap(LPCTSTR lpszResourceName); BOOL LoadBitmap(UINT nIDResource); BOO
-
C++中的哈希容器unordered_map使用示例
随着C++0x标准的确立,C++的标准库中也终于有了hash table这个东西. 很久以来,STL中都只提供<map>作为存放对应关系的容器,内部通常用红黑树实现,据说原因是二叉平衡树(如红黑树)的各种操作,插入.删除.查找等,都是稳定的时间复杂度,即O(log n):但是对于hash表来说,由于无法避免re-hash所带来的性能问题,即使大多数情况下hash表的性能非常好,但是re-hash所带来的不稳定性在当时是不能容忍的. 不过由于hash表的性能优势,它的使用面还是很广的,于是第三方
-
c++中map的基本用法和嵌套用法实例分析
本文实例讲述了c++中map的基本用法和嵌套用法.分享给大家供大家参考.具体分析如下: C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值.本文主要总结一下map基本用法和嵌套用法示例. 一.map基本用法 1. 头文件 复制代码 代码如下: #include <map> 2. 定义 复制代码 代码如下: map<int,int> my_Map; //注意这里的int和int可以是其他类型 或者是 复制代码 代码如下: t
-
海量数据处理系列之:用C++实现Bitmap算法
bitmap是一个十分有用的结构.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省. 适用范围:可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下基本原理及要点:使用bit数组来表示某些元素是否存在,比如8位电话号码扩展:bloom filter可以看做是对bit-map的扩展问题实例:1)已知某个文件内包含一些电话号码,每个号码为8位数字,统计不同号码的个数.8位最
-
C++中Semaphore内核对象用法实例
本文实例讲述了C++中Semaphore内核对象的用法,分享给大家供大家参考.具体方法如下: 复制代码 代码如下: // Semaphore.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> #include <process.h> HANDLE g_hSemaphore; DWORD g_nConut1 = 0; DWORD g_nConut2 = 0;
-
基于C++ map中key使用指针问题的详解
C++实际开发的过程会经常使用到map.map是一个key-value值对,key唯一,可以用find进行快速的查找.其时间复杂度为O(logN),如果采用for循环进行遍历数据时间复杂度为O(N).如果map中的数据量比较少时,采用find和for循环遍历的效率基本没有太大的区别,但是在实际的开发过程中,存储在map中的数据往往是大量的,这个时候map采用find方式效率比遍历效率高的多. 确定采用find方式查找数据后,我们需要考虑存储map的空间复杂度,对于基础数据类型的数据(int ch
-
C++中auto_ptr智能指针的用法详解
智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足以涵盖auto_ptr的大部分内容. auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者.当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有
-
C语言中枚举与指针的实例详解
C语言中枚举与指针的实例详解 总结一下, 定义枚举,用typedef enum关键字, 比如 typedef enum{Red,Green,Blue} Color3; 枚举到数值的转换,如果没有指定代表数值就是从0开始算, 比如 Color3 c=Red; printf("%d",c);会显示0, 除非指定 如typedef enum{Red=3,Green=5,Blue=10} Color3; 关于类型指针的定义, 定义的时候在变量名左边加*代表此变量只是一个空指针而已, 若需要赋
-
Vue中key的作用示例代码详解
Vue中key的作用 key的特殊attribute主要用在Vue的虚拟DOM算法,在新旧Nodes对比时辨识VNodes.如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改.复用相同类型元素的算法,而使用key时,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素.此外有相同父元素的子元素必须有独特的key,重复的key会造成渲染错误. 描述 首先是官方文档的描述,当Vue正在更新使用v-for渲染的元素列表时,它默认使用就地更新的策略,如果数据项的
-
C++中常量与指针的示例详解
前言 和指针联用有佷微妙的地方,之前一直佷晕,现在来继续研究下.诸如以下: int const; const int; const int* p; int const* p; int* const p; const int* const p; const 是一种处理符号常量的方法,以 const 声明的变量,一般首字母大写,声明之后无法被修改.相比于 define,const 会显式的指定类型.除定义符号外,一般可用于函数声明,表示函数不会修改任何值:用于参数,表示函数不会修改参数:甚至可以用于
-
Vue中key的作用及原理详解
目录 1. 先说结论 2. key的作用 2.1 举一个例子 2.2 修改一下上述示例 2.3 再修改一下示例 3. key的实现原理 1. key为index的情况. 2. key为id的情况. 总结 1. 先说结论 key在Vue是DOM对象的标识: 进行列表展示时,默认key是index: 如果数据只做展示使用,使用index作为key是没有任何问题的: 如果使用index作为key,而后续操作会破坏顺序,一定会带来效率问题,严重时会渲染出错误的DOM 关于key的作用及实现原理,下面一一
-
基于Android应用中如何反馈Crash报告的详解
为什么需要反馈Crash报告? 做Android应用程序,要尽量避免程序Crash的发生.虽然说零Crash是程序员追逐的最终目标,但是现实的情况是,程序员只能尽量的减少Crash的发生,而几乎不可能完全杜绝Crash.也许,你认为你的应用的健壮性已经近乎完美,轻松的经受住了测试部门魔鬼般的考验,但是当你的应用发布到市场,面对百万甚至千万级别的用户的时候,可能就没有那么幸运了. 基于以上原因,一般的应用程序,都要有一个Crash反馈的机制.程序员可以根据反馈的结果,对当前的版本的代码进行改进,使
-
PHP 基于Yii框架中使用smarty模板的方法详解
第一种方法按照YII系统的办法生成视图觉得有点麻烦,觉得用smarty更省事.尝试着把smarty模板加进来了. 复制代码 代码如下: date_default_timezone_set("PRC");class PlaceController extends CController {protected $_smarty;function __construct(){parent::__construct('place');//需要一个参数来调用父类的构造函数,该参数为控制器ID$p
-
C++中map和set的简介及使用详解
目录 关联式容器 键值对 set set的介绍 set的使用 multiset map map的介绍 map的使用 map构造 map的插入 map的[]运算符重载 multiset 关联式容器 关联式容器包括序列式容器和关联式容器 序列式容器: 底层为线性序列的数据结构,里面存储的是元素本身,包含vector.list.deque.forward_list(C++11)等.关联式容器: 里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高,包含set.map.u
-
基于C#调用c++Dll结构体数组指针的问题详解
C#调用c++dll文件是一件很麻烦的事情,首先面临的是数据类型转换的问题,相信经常做c#开发的都和我一样把学校的那点c++底子都忘光了吧(语言特性类). 网上有一大堆得转换对应表,也有一大堆的转换实例,但是都没有强调一个更重要的问题,就是c#数据类型和c++数据类型占内存长度的对应关系. 如果dll文件中只包含一些基础类型,那这个问题可能可以被忽略,但是如果是组合类型(这个叫法也许不妥),如结构体.类类型等,在其中的成员变量的长度的申明正确与否将决定你对dll文件调用的成败. 如有以下代码,其
随机推荐
- 从console.log说起(console.log详细介绍)
- asp执行带参数的sql语句实例
- Spring实现文件上传(示例代码)
- JS修改css样式style浅谈
- java程序打包成exe与jar的图文教程
- Java并发编程示例(二):获取和设置线程信息
- 详解Spring整合Quartz实现动态定时任务
- oracle(plsql)生成流水号
- 编写Python脚本使得web页面上的代码高亮显示
- 使MySQL能够存储emoji表情字符的设置教程
- php删除指定目录的方法
- Javascript中apply、call、bind的巧妙使用
- Perl中著名的Schwartzian转换问题解决实现
- JavaScript简单验证表单空值及邮箱格式的方法
- thinkphp 多表 事务详解
- JavaScript获取鼠标坐标的函数(兼容IE、FireFox、Chrome)
- mysql实现自动远程备份一办法
- 使用 Swift 语言编写 Android 应用入门
- 解析Java的InputStream类并借助其读取ppt文件
- PHP命名空间namespace的定义方法详解