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的限制和实值的开放修改。








 

posted on 2014-10-21 09:40  冰雨纷飞  阅读(1070)  评论(0编辑  收藏  举报

导航