代码改变世界

STL学习笔记---STL简介

2015-08-09 00:10  rangers  阅读(378)  评论(0编辑  收藏  举报

1.概述

STL是通用类模版和算法的集合,它提供给程序员一些标准的数据结构和算法的实现。STL三大关键组成:

  • 容器(Containers),用来管理类对象的集合
  • 迭代器(Iterators),用来在一个对象群集的元素上进行遍历动作。迭代器的主要好处是,为所有容器提供了一组很小的公共接口,利用这个接口,某项操作就可以行进至群集的下一个元素。迭代器的接口和一般的指针差不多,以operator++累进,以operator*提取所指的值。
  • 算法(Algorthms),用来处理群集里的元素。

STL的基本观念就是将数据操作分离。数据由容器类别加以管理,操作则由可定制的算法定义之,迭代器在两者之间充当粘合剂,使任何算法都可以和任何容器交互运作。
STL组件的合作

2、容器

STL容器分为两类:

  • 序列式容器(Sequence containers) 可序群集,其中每个元素均有固定的位置--取决于插入时机和地点,和元素值无关。
    vector
    deque
    list
    为序列式容器。

  • 关联式容器(Associative containers) 以序群集,元素位置取决于特定的排序准则。位置取决于元素值,和插入次序无关。
    set
    multiset
    map
    multimap
    为关联式容器。
    关联式容器依据特定的排序准则,自动为其元素排序。排序准则以函数形式呈现,用来比较元素值(value)或元素键值(key)。缺省情况下以operator<进行比较,可以定义自己的比较准则。

3、迭代器

迭代器是一个“可遍历STL容器内全部或部分元素的对象”,一个迭代器用来指出容器中的一个特定的位置。

基本操作如下:

(1) operator* 返回当前位置上元素的值

(2) operator++ 将迭代器前进至下一元素

(3) operator== 和 operator!= 判断两个迭代器是否指向同一位置。

(4) operator= 为迭代器赋值

所有容器类别都提供有一些成员函数,使我们得以获得迭代器并以之遍历所有的元素,这些函数中最重要的是:
begin()
返回一个迭代器,指向容器的起点
end()
返回一个迭代器,指向容器的结束点,结束点在最后一个元素之后。
注:begin()end()形成了一个半开区间,空区间的begin()等于end()

迭代器的型别:

(1)container::iterator 读写模式遍历元素
(2)constainer::const_iterator "只读"模式遍历元素

迭代器分类

(1)双向迭代器
双向迭代器可以双向行进,以递增运算或以递减运算后退。
list set multiset map multimap提供的迭代器都属此类。
(2)随机存储迭代器
不但具备双向迭代器的所有属性,还具备随机访问能力。
vector deque和string所提供的迭代器都属此类。

注:关于迭代器的使用有一个效率问题

list<char>::iterator pos;
for (pos = coll.begin(); pos != coll.end(); ++pos)
{
...
}
   
for (pos = coll.begin(); pos != coll.end(); pos++)
{
...
} //OK but slower

++pospos++的效率高,因为后者需要一个额外的临时对象来存放迭代器的原本位置并将它返回,所以一般情况下最好使用++pos

4、算法

算法并非容器类别的成员函数,而是一种搭配迭代器使用的全局函数。所以STL更多体现的是泛型式编程思维模式(generic functional programming paradigm),而不是面向对象模式(OOP paradigm).

注意:
(1)所有的算法都用来处理一个或多个区间内的元素,所以我们必须将区间首尾当做两个参数传给算法。调用者必须保证这个区间的有效性。
(2)所有算法处理的都是半开区间 [begin, end )。
(3)如果某个算法用来处理多个区间,那么当你调用它时,务必确保第二(以及其它)区间所拥有的元素个数,至少和第一区间的元素个数相同。

5、总结

  • STL的容器、迭代器、算法都是templates,因此可以操作任何型别,不论是STL预先定义好的或者是用户自行定义的都可以。
    STL容器元素必须满足的三个基本要求:
    (1)必须可以通过copy构造函数进行复制
    (2)必须可以通过assignment操作符完成赋值动作
    (3)必须可以通过析构函数完成销毁动作

  • STL只支持value语意,不支持reference语意。

  • STL的设计原则是效率优先,安全次之。错误检查相当花时间,所以STL几乎没有错误处理。所以对操作人员来说,要自己保证使用 STL 的正确性,或者自己增加一层包装来实现STL的安全性。

  • STL不是线程安全的。