前言

  最近正好刚刚看完,《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. Java 8 VM GC Tuning Guide Charter3-4

    第三章 Generations One strength of the Java SE platform is that it shields the developer from the compl ...

  2. 最火的.NET开源项目(转)

    综合类 微软企业库 微软官方出品,是为了协助开发商解决企业级应用开发过程中所面临的一系列共性的问题, 如安全(Security).日志(Logging).数据访问(Data Access).配置管理( ...

  3. win8 telnet VirtualBox中的redhat9

    1. VirtualBox设置网络连接为“桥接网卡”,并且此网卡要为win8正在使用的网卡(比如我的电脑上使用的就是无线网卡,则选择网卡时也要用无线网卡) 2. 在redhat的终端里,运行ifcon ...

  4. For和While在C和MATLAB中的区别——MATLAB的大坑

    For和while是常见的循环关键字,在许多语言中都是通用的.但是想必不是所有人,都被其中的区别困扰过,尤其是MATLAB“程序员”. x=[,,,,,,]; i=; while i<=leng ...

  5. Unix无缓冲文件操作函数、文件信息查询

    问题描述:         Unix无缓冲文件操作函数.文件信息查询 问题解决:        struct stat 结构体信息: 具体代码: 具体源文件:

  6. watch your tone

    老板要求邮件注意语气... 木想到混了这么久这种事情还要老板提醒

  7. [设计模式] 16 迭代器模式 Iterator Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...

  8. Java学习第三篇:类的三大特征,抽象类,接口,final关键字

    一.类的三大特征 1.封装性 (1).什么是封装 封装就是把抽象出的数据和对数据的操作封装在一起, 数据被保护在内部, 程序的其他部分只有通过被授权的操作(成员方法), 才能对数据进行操作. (2). ...

  9. 别让安全问题拖慢了 DevOps!

    DEVSECOPS 所面临的挑战 敏捷开发和 DevOps 方法的出现使软件开发的速度与质量都有所提升,但它们不经意地也为安全机构增压不少.从前的安全策略是基于静态数据的,而在产品上线前才应用这些策略 ...

  10. NSOJ10050 Newspaper Headline

    题意:给你一个<10^4的S串和<10^6的T串,通过将S串重复k次,然后将其中一些多余的字母删掉可以获得T串,问k最小是多少,没有的话输出1. 思路:对于每个T串里的字母,我们从左到右扫 ...