STL学习记录(1) - 顺序式容器

0. 序

学习STL源码做的笔记,主线是侯捷老师的《STL源码剖析》。
本文中部分图片来自侯捷老师的PPT。

1. list

list是一个双向链表。
list容器的iterator也是一个类,需要重载*操作符、两个++的运算。因为list所占的内存空间不一定是连续的,可能是跳跃的。
iterator中至少有5个typedef(不只是list的迭代器,其他容器也是如此)

在链表尾部,刻意加了一个空节点,与“前闭后开”的思想吻合。

iterator必须能够回答algorithm的5个提问(但是实际上目前只用了3个):
在这里插入图片描述
但是STL中的算法,参数不一定是class,可能就是一个一般的指针比如 int* 呢?那就不能直接问,需要间接的问,所以,在标准中加入了一个中介:迭代器萃取机(iterator traits)。算法先问萃取机,萃取机再问迭代器(指针)。

在这里插入图片描述
注意上图中的右下角框。value_type的目的是为了声明变量,既然是声明变量,那么加上一个const的话,所声明的这个变量就不能被更改,这没有意义,所以当iterator有const修饰的时候,返回值不能带有const修饰。

完整的5个回答,如下(用的都是偏特化):
在这里插入图片描述

2. vector

每次空间(capacity)是两倍增长。
在这里插入图片描述

vector内部只用三个指针:

  • start
  • finish
  • end_of_storage
    所以,一个vector的空间大小是3个指针的大小。
    在这里插入图片描述

因为vector的内部空间是连续的,所以vector的iterator不用做成class,只用一个普通的指针就可以了。

3. array

array就是对c语言中的数组进行封装,以更好的方式适应STL中的算法。
实现起来比较简单:
在这里插入图片描述
因为就是一个简单的封装,所以array没有构造函数,也没有析构函数。

4. forward_list

与双向链表list类似,只不过双向变成了单向。
在这里插入图片描述

5. deque

在这里插入图片描述

deque容器,对外连续,但内部分段实现。
内部有一个vector(类的内部命名为map),vector中每个元素保存的是一段内存空间buffer的地址。

与list类似,他所使用的内存空间可能不连续,所以deque内部的迭代器iterator也必须封装成一个class,以实现复杂的操作。
deque的iterator有4个指针:

  • cur:指向buffer中具体的那个元素
  • first:当前buffer的起始地址,防止iterator运算时越界
  • last:当前buffer的最后地址(最后一个元素的下一个),防止iterator运算时越界
  • node:记录deque中的这个元素,在内部vector中哪个下标所指的buffer内

每个deque的大小:
有两个迭代器,每个迭代器有4个指针,所以就是8个指针。
另外,还有一个内部的vector(内部名为map)的指针和map_size的指针。
一共10个指针,所以一个deque的大小就是10个指针的大小。
在这里插入图片描述

deque如何模拟连续?

在这里插入图片描述
(这是 GNU 4.9的图,相比GNU 2.9的实现来说,它搞复杂了)
连续的模拟,都是deque迭代器的功劳。
deque.size()方法中,是finish-start两个迭代器做减法,所以一定对迭代器做了重载(两个迭代器之间有多少buffer,再乘以每个buffer的大小,在加上首尾两个buffer的部分)。
在这里插入图片描述
对外是连续的容器,都应该提供+=、-=以及下标访问的访问方式。

6. queue

  • queue先进先出。
  • queue内含一个其他容器,但是限制该容器的某些功能。
  • 在c++中,定义一个queue时,第二个参数可以指定queue内部使用的容器,比如list或者deque,默认是deque。但是queue的底层不能使用vector实现,因为vector没有pop方法。但是编译会过,因为类模板在编译时是没有检查的,类模板中方法是在调用时才创建。
  • queue本身的功能限制了它没有迭代器,STL也没有提供迭代器。
  • 不能用set或map做底层支撑。
    在这里插入图片描述

7. stack

  • stack先进后出。
  • 与queue一样,stack也是内含一个其他容器,但是限制该容器的某些功能。
  • 在c++中,定义一个stack时,第二个参数可以指定queue内部使用的容器,比如list、vector或者deque,默认是deque。
  • 本身的功能限制了它没有迭代器,STL也没有提供迭代器。
  • 不能用set或map做底层支撑。
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值