zoukankan      html  css  js  c++  java
  • STL源码中map和set中key值不能修改的实现

    前言


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

    set容器中的实现


      set中具体怎么实现的,看源码是最清楚的,下面就是set的部分源码:
     1 class set 
     2 {
     3     ......
     4 private:
     5     typedef rb_tree<key_type, value_type, 
     6         identity<value_type>, key_compare, Alloc> rep_type;
     7     rep_type t;  // red-black tree representing set
     8 public:
     9     typedef typename rep_type::const_pointer pointer;
    10     typedef typename rep_type::const_pointer const_pointer;
    11     typedef typename rep_type::const_reference reference;
    12     typedef typename rep_type::const_reference const_reference;
    13     typedef typename rep_type::const_iterator iterator;   // iterator定义为红黑树的const_iterator
    14     typedef typename rep_type::const_iterator const_iterator;
    15     typedef typename rep_type::const_reverse_iterator reverse_iterator;
    16     typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
    17     typedef typename rep_type::size_type size_type;
    18     typedef typename rep_type::difference_type difference_type;
    19     ......
    20 }

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

    map容器中的实现


      同样,也是先看看map中有关的源码,然后结合源码分析,部分源码如下:
     1 class map {
     2 public:
     3 
     4     ......
     5     // typedefs:
     6 
     7     typedef Key key_type;
     8     typedef T data_type;
     9     typedef T mapped_type;
    10     typedef pair<const Key, T> value_type;   //value_type的定义
    11 
    12 
    13     typedef Compare key_compare;
    14 
    15 private:
    16     typedef rb_tree<key_type, value_type, 
    17         select1st<value_type>, key_compare, Alloc> rep_type;  // rb_tree的定义
    18 
    19     rep_type t;  // red-black tree representing map
    20 public:
    21     typedef typename rep_type::pointer pointer;
    22     typedef typename rep_type::const_pointer const_pointer;
    23     typedef typename rep_type::reference reference;
    24     typedef typename rep_type::const_reference 
    25         typedef typename rep_type::iterator iterator;    // iterator的定义
    26 
    27     typedef typename rep_type::const_iterator const_iterator;
    28     typedef typename rep_type::reverse_iterator reverse_iterator;
    29     typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
    30     typedef typename rep_type::size_type size_type;
    31     typedef typename rep_type::difference_type difference_type;
    32     ......
    33 }

      虽然map中的key值也是不能修改的,但是其中实值是可以修改的,所以map的迭代器不能是const_iterator,由上面的源码也可以看出。那么key值不允许修改是怎么实现的?map底层实现是通过红黑树实现的,其中红黑树的定义为
    1     typedef rb_tree<key_type, value_type, 
    2         select1st<value_type>, key_compare, Alloc> rep_type;  // rb_tree的定义
    可以看到其中红黑树存储值的类型是value_type,而value_type定义是:
    1 typedef pair<const Key, T> value_type;   //value_type的定义
      对于一个map容器,每次插入、删除或者查找返回的迭代器,其指向的红黑树中node节点,对其iterator->,解出的值的类型是value_type,这是一个pair的包装类,这个,我们定义了它的Key为const Key,而其值的类型为T,这样对于每次返回的迭代器,我们就可以实现,其中Key为const类型不能修改,对于实值不是const,可以修改。
      这样就实现了对其的key的限制和实值的开放修改。








  • 相关阅读:
    vue手机号正则表达式
    工作中linux常用命令速记!
    Mac os 升级到Catalina 之后的问题
    NX二次开发-UFUN获取某个部件或对象事例的父部件或对象事例(PartOcc)UF_ASSEM_ask_part_occurrence
    C#例子1(WinForm窗体开发)-带图形列表的系统登录程序
    NX二次开发-C#多线程技术做exe外部开发(批量导出PDF图纸例子)
    NX二次开发-C#使用DllImport调用libugui.dll里的内部函数自动将NX标题设置为prt路径例子(三部曲3)
    NX二次开发-C#使用DllImport调用libufun.dll里的UF函数学习方法及tag转handle例子(三部曲2)
    NX二次开发-C#创建XML和解析XML
    NX二次开发-C#使用DllImport调用libufun.dll里的UF函数(反编译.net.dll)调用loop等UF函数(三部曲1)
  • 原文地址:https://www.cnblogs.com/wangjzh/p/4049599.html
Copyright © 2011-2022 走看看