入门篇!带你概览STL历史与实现版本、以及其六大组件(容器、算法、迭代器、仿函数、配接器、配置器)

一、STL概论

  • 长久以来,软件界一直希望建立一种可重复运用的东西, 以及一种得以制造出“可重复运用的东西”的方法,让工程师/程序员的心血不 致于随时间迁移、人事异动 、私心欲念、人谋不臧 而烟消云散。从子程序(subroutines)、程序(procedures)、 函式(functions)、类别(classes),到函式库(function libraries)、类别库(class libraries)、各种组件(components),从结构化设计、模块化设计、面向对象 (object oriented)设计,到样式(patterns)的归纳整理,无一不是软件工程的漫漫奋斗史。
  • 为的就是复用性(reusability)的提升。
  • 复用性必须建立在某种标准之上——不论是语言层次的标准,或数据交换的标准, 或通讯协议的标准。但是,许多工作环境下,就连软件开发最基本的数据结构 (data structures)和算法(algorithms)都还迟迟未能有一套标准。大量程序员被迫从事大量重复的工作,竟是为了完成前㆟早已完成而自己手上并未拥有的程序代码。 这不仅是人力资源的浪费,也是挫折与错误的来源。
  • 为了建立数据结构和算法的一套标准,并且降低其间的耦合(coupling)关系以提升各自的独立性、弹性、互操作性(相互合作性,interoperability),C++社群里诞生了 STL。
  • STL 的价值在两方面:
    • 低层次而言,STL 带给我们一套极具实用价值的零组件, 以及一个整合的组织。这种价值就像 MFC 或 VCL 之于 Windows 软件开发过程 所带来的价值一样,直接而明朗,令大多数人有最立即明显的感受。
    • 除此之外 STL 还带给我们一个高层次的、以泛型思维(Generic Paradigm)为基础的、系统化的、 条理分明的「软件组件分类学(components taxonomy)」。从这个角度来看,STL 是个抽象概念库(library of abstract concepts),这些「抽象概念」包括最基础的 Assignable(可被赋值)、Default Constructible(不需任何自变量就可建构)、 Equality Comparable(可判断是否等同)、LessThan Comparable(可比较大 小)、Regular (正规)…,高阶一点的概念则包括 Input Iterator(具输入功能的迭代器)、 Output Iterator(具输出功能的迭代器)、Forward Iterator(单向迭代器)、 Bidirectional Iterator(双向迭代器)、Random Access Iterator(随机存取迭代 器)、Unary Function (一元函式)、Binary Function(为元函式)、Predicate(传回真假值的一元判断 式)、Binary Predicate(传回真假值的二元判断式)…
    • 更高阶的概念包括 sequence container(序列式容器)、associative container(关系型容器)…
  • STL 的创新价值便在于具体叙述了上述这些抽象概念,并加以系统化。 换句话说,STL 所实现的,是依据泛型思维架设起来的一个概念结构。这个以抽 象概念(abstract concepts)为主体而非以实际类别(classes)为主体的结构,形成 了一个严谨的接口标准。在此接口之下,任何组件有最大的独立性,并以所谓迭 代 器(iterator)胶合起来,或以所谓配接器(adapter)互相配接,或以所谓仿函 式 (functor)动态选择某种策略(policy 或 strategy)。
  • 目前没有任何一种程序语言提供任何关键词(keyword)可以实质对应上述所谓的 抽象概念。但是 C++ classes 允许我们自行定义型别,C++ templates 允许我们将型别参数化,藉由两者结合并透过traits编程技法,形成了 STL 的绝佳温床。

二、STL历史

  • STL系由 Alexander Stepanov创造于1979年前后,这也正是Bjarne Stroustrup 创造C++的年代。虽然 David R. Musser 于 1971 开始即在计算器几何领域中发展并倡导某些泛型程序设计观念,但早期并没有任何程序语言支持泛型编程
  • 第一 个支持泛型概念的语言是 Ada。Alexander 和 Musser 曾于 1987 开发出㆒套相关的 Ada library。然而 Ada 在美国国防工业以外并未被广泛接受,C++ 却如星火燎原 般地在程序设计领域中攻城略地。当时的C++ 尚未导入template 性质,但Alexander 却已经意识到,C++ 允许程序员透过指针以极佳弹性处理内存,这一点正是既 要 求㆒般化(泛型)又不失效能的一个重要关键
  • 更重要的是,必须研究并实验出一个“建立在泛型编程之上”的组件库完整架构。 Alexander 在AT&T 实验室以及惠普公司的帕罗奥图(Hewlett-Packard Palo Alto) 实验室,分别实验了多种架构和算法公式,先以C 完成,而后再以 C++ 完成。 1992 年 Meng Lee 加入 Alex 的项目,成为 STL 的另一位主要贡献 者。
  • 贝尔(Bell)实验室的 Andrew Koenig 于1993 年知道这个研究计划后,邀请 Alexander 于是年 11 月的 ANSI/ISO C++ 标准委员会会议上展示其观念。获得热 烈回应。 Alexander 于是再接再励于次年夏天的 Waterloo(滑铁卢)会议开幕 前,完成正式提案,并以压倒性多数一举让这个巨大的计划成为 C++ 标准规格的 意部份。

三、STL与C++标准链接库

  • 1993/09,Alexander Stepanov 和他一手创建的 STL,与 C++ 标准委员会有了第一次接触。
  • 当时 Alexander 在硅谷(圣荷西)给了C++ 标准委员会一个演讲,讲题是:The Science of C++ Programming。题目很理论,但很受欢迎。1994/01/06 Alexander 收到 Andy Koenig(C++ 标准委员会成员,当时的 C++ Standard 文件审核编辑)来信,言明 如果希望 STL 成为 C++ 标准链接库的一部份,可于 1994/01/25 前送交一份提案 报告到委员会。Alexander 和 Lee 于是拼命赶工完成了那份提案。
  • 然后是 1994/03 的圣地牙哥会议。STL 在会议上获得了很好的回响,但也有许多 反对意见。主要的反对意见是,C++ 即将完成最终草案,而 STL 却是如此庞大, 似乎有点时不我予。投票结果压倒性地认为应该给予这份提案一个机会,并把决 定 性投票延到下次会议。
  • 下次会议到来之前,STL 做了几番重大的改善,并获得诸如 Bjarne Stroustrup、 Andy Koenig 等人的强力支持。
  • 然后便是滑铁卢会议。这个名称对拿破仑而言,标示的是失败,对Alexander 和 Lee, 以及他们的辛苦成果而言,标示的却是巨大的成功。投票结果,80 % 赞 成,20 % 反 对,于是 STL 进入了 C++ 标准化的正式流程,并终于成为 1998/09 定案的 C++ 标 准规格中的 C++ 标准链接库的一大脉系。影响所及,原本就有的 C++ 链接库如 stream, string 等也都以 template 重新写过。到处都是 templates! 整个 C++ 标准 链接库呈现「春城无处不飞花」的场面。
  • Dr Dobb's Journal 曾于 1995/03 刊出一篇名为 Alexander Stepanov and STL 的访谈 文 章,对于 STL 的发展历史、Alexander 的思路历程、STL 纳入 C++ 标准链接库 的 过程,均有详细叙述。

四、STL的实现版本

HP实现版本

  • HP版本是所有 STL实作版本的始祖。
  • 每一个HP STL 表头档都有如下一份声明, 允许任何人免费使用、拷贝、修改、传布、贩卖这份软件及其说明文件,唯一需要遵守的是,必须在所有档案中加上 HP 的版本声明和运用权限声明。这种授权并不属于GNU GPL范畴,但属于open source范畴。

P.J.Plauger实现版本

  • P.J. Plauger版本由P.J. Plauger发展。 PJ 版本承继HP版本,所以它的每一个表头档都有 HP 的版本声明,此外还加上P.J. Plauger 的个人版权声明:

  • 这个产品既不属于 open source范畴,更不是GNU GPL。
  • P.J. Plauger 版本被Visual C++采用,所以可以在 Visual C++软件安装的 "include" 子目录下找到所有STL表头档,但是不能公开它或修改它或甚至贩卖它。

  • 由于 Visual C++ 对C++语言特性的支持不甚理想,导致PJ版本的表现也受影响。
  • 这项产品目前由 Dinkumware 12公司提供服务。

Rouge Wave实现版本

  • RougeWave 版本由 Rouge Wave 公司开发。RW 版本承继HP版本,所以它的每一个表头档都有 HP 的版本声明,此外还加上Rouge Wave 的公司版权声明:
  • 这份产品既不属于open source 范畴,更不是GNU GPL。
  • Rouge Wave 版本被C++Builder采用,所以当然你可以在C++Builder 的 "include" 子目录下找到所有STL表头档,但是不能公开它或修改它或甚至贩卖它。
  • C++Builder 对 C++ 语言特性的支持相当不错,连带地给予了 RW 版本正面的影响。

STLport实现版本

  • 网络上有个 STLport 站点,提供一个以SGI STL为蓝本的高度可移植性实作版本。

SGI STL实现版本

  • SGI 版本由Silicon Graphics Computer Systems, Inc.公司发展,承继HP版本。所以它的每一个表头档也都有 HP 的版本声明。此外还加上SGI 的公司版权声明。 从其声明可知,它属于 open source 的一员,但不属于 GNU GPL(广泛开放授 权)。

  • SGI 版本被GCC采用。你可以在 GCC 的 "include" 子目录下(例如 C:\cygnus\ cygwin-b20\include\g++)找到所有STL表头档,并获准自由公开它或修改它或甚至贩卖它。
  • GCC 对C++语言特性的支持相当良好,在 C++ 主流编译程序中表现耀眼,连带地给予了SGI STL 正面影响。事实上SGI STL 为了高度移植性,已经考虑了不同编译器的不同的编译能力,详见后面文章介绍的<stl_config.h>头文件。
  • SGI STL也采用某些 GPL(广泛性开放授权)档案,例如<std\complext.h>、<std\complext.cc>、<std\bastring.h>、<std\bastring.cc>。这些文件都有如下的声明:

五、STL的六大组件

  • 容器(containers):
    • 各种数据结构,如vector, list, deque, set,map,用来存放数据
    • 从实作的角度看,STL 容器是一种class template。就体积而言,这一部份很像冰山在海面下的比率
  • 算法(algorithms):
    • 各种常用算法如sort,search,copy,erase…
    • 从实作的角度看,STL算法是一种function template
  • 迭代器(iterators):
    • 扮演容器与算法之间的胶着剂,是所谓的“泛型指标”。共有五种类型,以及其他衍生变化。
    • 从实作的角度看, 迭代器是一种将 operator*, operator->, operator++, operator--等指标相关操作予以多载化的class template。所有STL容器都附带有自己专属的迭代器——是的,只有容器设计者才知道如何遍历自己的元素。原生指标(native pointer)也是一种迭代器。
  • 仿函式(functors):
    • ​​​​​​​行为类似函式,可做为算法的某种策略(policy)
    • 从实作的角度看,仿函式是一种重载了operator()的class或class template。一般函式指标可视为狭义的仿函式
  • 配接器(adapters):
    • ​​​​​​​一种用来修饰容器(containers)或仿函式(functors) 或迭代器(iterators)接口的东西
    • 例如STL提供的queue和stack,虽然看似容器,其实只能算是一种容器配接器,因为它们的底部完 全借重 deque,所有动作都由底层的 deque 供应。改变functor接口者,称 为function adapter,改变 container 接口者,称为 container adapter,改变 iterator 接口者,称为 iterator adapter
  • 配置器(allocators):
    • ​​​​​​​负责空间配置与管理
    • 从实作的角度 看, 配置器是一个实现了动态空间配置、空间管理、空间释放的 class template。
  • 六大组件的交互关系:


  • 我是小董,V公众点击"笔记白嫖"解锁更多【C++ STL源码剖析】资料内容。

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值