前言

  最近正好刚刚看完,《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. 【BZOJ 1006】[HNOI2008]神奇的国度

    Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系 ...

  2. Careercup - Facebook面试题 - 5671785349513216

    2014-05-02 01:05 题目链接 原题: bool anaStrStr (string needle, string haystack) { } Write a function that ...

  3. OC 加密

    //MD5加密的结果为128位的二进制数. //所以有128 / 8 = 16字节(8位一个字节). //每八位表示两个16进制数. //MD5 有32个16进制数. //语言层次的所有摘要算法步骤类 ...

  4. Flex显示麦克风当前音量

    Flex动态显示麦克风当前音量 效果: 代码: <?xml version="1.0" encoding="utf-8"?> <s:Appli ...

  5. bitmap缩放时抗锯齿

    bitmap在进行放大缩小的时候经常会出现边缘锯齿的情况,通常的解决办法是在Paint中加入抗锯齿, paint.setAntiAlias(true); 但是有时候发现这并没有起到抗锯齿的作用,这是可 ...

  6. WinForm中Component Class、User Control及Custom Control的区别和使用-转

    转http://www.cnblogs.com/jhtchina/archive/2010/11/28/1028591.html NET Framework 为您提供了开发和实现新控件的能力.除了常见 ...

  7. asp.net asp:TextBox控件绑定值后,获取不到新值问题解决方法

    把Page_Load里绑定的代码放在    if(!IsPostBack){}里面后,即可获取到更新的值. 意思为第一次加载执行.

  8. jQuery+AJAX实现网页无刷新上传

    新年礼,提供简单.易套用的 jQuery AJAX上传示例及代码下载.后台对文件的上传及检查,以 C#/.NET Handler 处理 (可视需要改写成 Java 或 PHP). 有时做一个网站项目 ...

  9. 【BZOJ】【1965】SHUFFLE 洗牌

    扩展欧几里德+快速幂 每次转换位置:第x位的转移到2*x %(n+1)这个位置上 那么m次后就到了(2^m)*x %(n+1)这个位置上 那么找洗牌m次后在 l 位置上的牌就相当于解线性模方程: (2 ...

  10. 清除HTML中的特殊字符

    /// <summary>        /// 清楚HTML中的特殊字符        /// </summary>        /// <param name=&q ...