最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的《STL源码剖析》。之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限个人感受),在技术上他们比较严谨,在为人处世上也非常谦虚,所以一些台湾的技术资料我觉得是值得一看的。

想要学习STL源码的设计,其实应该是从空间适配器(allocator)和迭代器(iterators)开始看起的,但是我没有对这两个部分做深入研究,主要原因是最近实在太忙,要写论文又要兼顾找工作,不能在这上面投入太大精力,而这两个部分又不太容易看懂,所以我决定先从容器开始看起,这样在编码时用到c++标准库的时候会更有底气。

关于容器的设计,其实我们在算法与数据结构课程里都涉及过,但是当时主要集中于理解设计理念,没有真正编过一套完整的库去应用我们学习到的知识,所以读者在学习c++标准库的时候我觉得应该结合过去数据结构的知识,关注它实现的技巧和为什么这么实现,通过学习优秀代码提升自己的编程能力。

容器分为序列式容器与关联式容器,本篇博客主要讨论序列式容器,所谓序列式容器,其中的元素都可序(ordered),但是未必有序(sorted)。C++本身提供了一个序列式容器array,STL另外再提供vector、list、deque,再以此为基础实现heap(内含vector),stack和queue(内含deque),后面会展开叙述,其实这里的stack和queue只是将deque改头换面而形成的,技术上被归类为一种配接器(adapter)。

由于篇幅,本文还是从使用者的角度介绍各个接口的设计思路。

Vector

Vector的迭代器

vector维护的是一个连续线性的空间,所以它的迭代器很好实现,只需要一个普通指针就可以(和元素类型无关),迭代器所需要的操作行为包括:operator*,operator->,operator++,operator--,operator+,operator-,operator+=,operator-=,普通指针天生就具备。,vector支持随机存取,它提供的是Random Access Iterators,普通指针也有这样的能力。所以,如果客户端写出这样的代码:

vector<int>::iterator ivite;

那么ivite的类型就是int *。

vector的构造与内存管理

vector里面有三个迭代器,start、finish、end_of_storage,分别指向当前连续空间所使用的头和尾、整块连续空间的尾。为了降低空间配置时的速度成本,vector实际配置的大小要比客户端需求量更大一些,以备将来的使用。vector空间的增长实际上是一个浩大的工程,开销非常大,它需要申请一块新的连续空间,然后把已有的内容拷贝过去,这里面每次新扩充的空间都是原空间的两倍大,这样做可以把扩充空间的时间复杂度降低到O(n),如果每次新扩充的空间相比于原空间增加一个固定的大小m,那么无论m取何值,都可以证明最后的时间复杂度正比于n的平方。

vector元素操作:push_back,pop_back,erase,clear,insert

void push_back(const T& x) //将元素插入于vector的尾端,该函数首先检查是否还有备用空间,如果有就直接在备用空间上构造元素,调整迭代器finish,如果没有备用空间,就
//扩充空间(重新配置、移动数据、释放原空间)
void pop_back() //将尾端元素删除。
iterator erase(iterator first,iterator last) //删除[first,last)中的所有元素
iterator erase(iterator position) //清除某个位置上的元素
void clear() //清除所有元素
void insert(iterator postion,size_type n,const T& x) //从position开始,插入n个元素,元素初值为x

list

list和vector是两个最常用的容器,list的特点是:每次插入或删除一个元素,就配置或释放一个元素空间。list对于空间的运用有绝对的精准,而且对于任意位置的元素插入或删除的时间复杂度是O(1),但是list不支持随机访问,它只能从头开始遍历元素,这点不如vector,因此它们的使用需要根据具体的情况具体分析。

list的迭代器

list不像vector一样可以用普通指针作为迭代器,因为其结点不保证在存储空间中连续存在。list迭代器需要能够指向list的节点,并且可以进行正确的递增、递减、取值操作、成员取用操作,其实都很简单,这里不列代码了。

最新文章

  1. “英雄之旅”见闻和小结----angular2系列(三)
  2. Excel顺序生成序号,不能有数字4出现
  3. Orchard分类Taxonomies图文教程
  4. 转一下大牛的嵌入web页播放视频方法(转)
  5. objective-c(协议)
  6. windows 7 下,如何统计某文件夹下 视频总时长
  7. codevs 1507酒厂选址
  8. Buffer cache 的调整与优化
  9. 关于bootStrapdialog 学习心得
  10. error C2440
  11. wcf 给net.tcp 加mex
  12. HTML5 在canvas绘制一个矩形
  13. Angular4.0.0正式版发布
  14. 修复TortoiseGit文件夹和文件图标不显示
  15. 《Unbroken》
  16. PHP常用180函数总结【初学者必看】
  17. sublime Text 正则表达式功能使用介绍
  18. java算法----排序----(6)希尔排序(最小增量排序)
  19. 零基础照样做RNA-seq差异分析
  20. C#-派生类

热门文章

  1. [知了堂学习笔记]_牵线Eclipse和Tomcat第二篇 —— 安装Tomcat&amp;&amp;添加Tomcat到Eclipse
  2. 以守护进程的方式部署flask
  3. jQuery hover() 方法
  4. maven项目使用jacoco插件检测代码覆盖率详细配置
  5. _3_body_标签
  6. Java多线程之线程其他类
  7. php加入环境变量
  8. js给页面添加滚动事件并判断滚动方向
  9. 集中式(SVN)和分布式(Git)版本控制系统的简单比较
  10. 在IAR下移植CC2650 contiki工程