前言

  最近正好刚刚看完,《stl源码剖析》这本书的map和set的源码部分。但是看完之后又突然发现,之前怎么没有注意到map和set容器中key不能修改是怎么实现的。故,特此整理如下。

set容器中的实现

  set中具体怎么实现的,看源码是最清楚的,下面就是set的部分源码:
 class set
{
......
private:
typedef rb_tree<key_type, value_type,
identity<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing set
public:
typedef typename rep_type::const_pointer pointer;
typedef typename rep_type::const_pointer const_pointer;
typedef typename rep_type::const_reference reference;
typedef typename rep_type::const_reference const_reference;
typedef typename rep_type::const_iterator iterator; // iterator定义为红黑树的const_iterator
typedef typename rep_type::const_iterator const_iterator;
typedef typename rep_type::const_reverse_iterator reverse_iterator;
typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
typedef typename rep_type::size_type size_type;
typedef typename rep_type::difference_type difference_type;
......
}

  从其中的set的迭代器的定义,我们可以看出set的iterator定义为rep_type::const_iterator,这样获取的set的迭代器默认就是常量迭代器,自然就不能去修改set中的key值。

map容器中的实现

  同样,也是先看看map中有关的源码,然后结合源码分析,部分源码如下:
 class map {
public: ......
// typedefs: typedef Key key_type;
typedef T data_type;
typedef T mapped_type;
typedef pair<const Key, T> value_type; //value_type的定义 typedef Compare key_compare; private:
typedef rb_tree<key_type, value_type,
select1st<value_type>, key_compare, Alloc> rep_type; // rb_tree的定义 rep_type t; // red-black tree representing map
public:
typedef typename rep_type::pointer pointer;
typedef typename rep_type::const_pointer const_pointer;
typedef typename rep_type::reference reference;
typedef typename rep_type::const_reference
typedef typename rep_type::iterator iterator; // iterator的定义 typedef typename rep_type::const_iterator const_iterator;
typedef typename rep_type::reverse_iterator reverse_iterator;
typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
typedef typename rep_type::size_type size_type;
typedef typename rep_type::difference_type difference_type;
......
}

  虽然map中的key值也是不能修改的,但是其中实值是可以修改的,所以map的迭代器不能是const_iterator,由上面的源码也可以看出。那么key值不允许修改是怎么实现的?map底层实现是通过红黑树实现的,其中红黑树的定义为
     typedef rb_tree<key_type, value_type,
select1st<value_type>, key_compare, Alloc> rep_type; // rb_tree的定义
可以看到其中红黑树存储值的类型是value_type,而value_type定义是:

 typedef pair<const Key, T> value_type;   //value_type的定义
  对于一个map容器,每次插入、删除或者查找返回的迭代器,其指向的红黑树中node节点,对其iterator->,解出的值的类型是value_type,这是一个pair的包装类,这个,我们定义了它的Key为const Key,而其值的类型为T,这样对于每次返回的迭代器,我们就可以实现,其中Key为const类型不能修改,对于实值不是const,可以修改。
  这样就实现了对其的key的限制和实值的开放修改。

STL源码中map和set中key值不能修改的实现的更多相关文章

  1. 3D语音天气球(源码分享)——在Unity中使用Android语音服务

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3 ...

  2. Hbase源码分析:Hbase UI中Requests Per Second的具体含义

    Hbase源码分析:Hbase UI中Requests Per Second的具体含义 让运维加监控,被问到Requests Per Second(见下图)的具体含义是什么?我一时竟回答不上来,虽然大 ...

  3. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

  4. 第74讲:从Spark源码的角度思考Scala中的模式匹配

    今天跟随王老师学习了从源码角度去分析scala中的模式匹配的功能.让我们看看源码中的这一段模式匹配: 从代码中我们可以看到,case RegisterWorker(id,workerHost,.... ...

  5. OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa

    元数据最本质.最抽象的定义为:data about data (关于数据的数据).它是一种广泛存在的现象,在许多领域有其具体的定义和应用. JDBC中的元数据,有数据库元数据(DatabaseMeta ...

  6. Android多线程之(一)View.post()源码分析——在子线程中更新UI

    提起View.post(),相信不少童鞋一点都不陌生,它用得最多的有两个功能,使用简便而且实用: 1)在子线程中更新UI.从子线程中切换到主线程更新UI,不需要额外new一个Handler实例来实现. ...

  7. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  8. 【转载】STL"源码"剖析-重点知识总结

    原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...

  9. STL源码剖析 迭代器(iterator)概念与编程技法(三)

    1 STL迭代器原理 1.1  迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...

随机推荐

  1. 0x02全局变量和局部变量

    全局变量在什么地方定义? .data和.data? 格式如下: 变量名 类型 初始值1,初始值2... 变量名 类型 重复数 dup(初始值1,初始值2,...) 变量名 类型 ? 类型有哪些? 字节 ...

  2. 【转载】使用Axure制作App原型怎样设置尺寸?

    使用Axure制作App原型怎样设置尺寸? 原文地址:http://www.axure.us/2172/ 本文由原型库网站投稿,转载请注明出处. 最近有几位小伙伴儿都提出同样一个疑问:想用Axure设 ...

  3. 包装设计模式的实现以改进BufferedReader中的readLine方法为例

    实现与目标对象相同的接口     BufferedReader 定义一个变量记住目标对象 定义一个构造器接收被增强对象 覆盖需要增强的方法 对于不想增强的方法,直接调用目标对象的方法. package ...

  4. 动态更新Toolbar Menu以及Menu中同时显示文字和图标

    动态更新Toolbar Menu以及Menu中同时显示文字和图标 我们经常会有这样的需求,在切换Fragment或者点击某个按钮后动态更新Toolbar上Menu项.但是onCreateOptions ...

  5. html+css学习笔记 3[浮动]

    inline-block/float(浮动) 回顾:inline-block 特性:      1.块在一排显示 2.内联支持宽高 3.默认内容撑开宽度 4.标签之间的换行间隙被解析(问题) 5.ie ...

  6. mongodb 的安装历程

    mongo 安装历程 mongo的安装方法有千万种,只有一种让我觉得还不错,说说安装过程中的一点心德. 方法一:源码安装,千万别用这种方法,尼马我用虚拟机编译了一下午,竟然没有编译完,强制关机,第二天 ...

  7. Java多线程——<三>简单的线程执行:Executor

    一.概述 按照<Java多线程——<一><二>>中所讲,我们要使用线程,目前都是显示的声明Thread,并调用其start()方法.多线程并行,明显我们需要声明多个 ...

  8. SQL SERVER 之 填充因子

    填充因子依附索引而存在,但创建索引,就意味着要对表进行DML时,必须处理额外的工作量(也就是对索引结构的维护)以及存储方面的IO开销. 所以创建索引时,需要考虑创建索引所带来的查询性能方面的提高,与引 ...

  9. 【AutoMapper】实体类间自动实现映射关系,及其转换。

    官方项目下载: http://automapper.codeplex.com/ 博文 http://www.iteye.com/blogs/tag/AutoMapper 图解: 第一步:创建映射Map ...

  10. Checkbox框全选操作,form表单提交与jquery ajax提交两种处理方式

    //1.jquery ajax<script type="text/javascript"> $(function(){ var basePath = $(" ...