持之以恒
分类: C/C++
2009-06-20 23:08:52
STL是由一些可适用于不同的需求的集群类别(Collection classes),和一些能够在这些数据集群上运作的算法构成。
我认为STL:结构大量的使用了Observer(观察者)模式,在std这个namespace内
包括:
1) 容器:用来管理某类数据的集合
2) 迭代器:用来在一个对象集群上进行遍历动作,为容器提供了一组很小的公共接口,封装了容器实现具体采用的数据结构,所以每一种容器都有其相应的迭代器。
3) 仿函数(函数对象):
4) 算法:处理集群中的元素
STL的基本的观念是将数据和操作相分离。数据是由容器加以管理,而操作是由可定制的算法定义之,迭代器在两者之间充当粘合剂,使任何的算法都可以和任何的容器交互运作。
这样做的目的:在一个很小的框架内获得弹性。
通过特定的适配器(比如函数适配器)和仿函数,你可以补充、约束、定制算法。
两种类别的容器:
序列式容器(Vector Deque List)可序集群,元素的位置,取决于插入的次序
关联式容器(Set MulitiSet Map MutiMap),已序集群,元素的位置取决于特定的排序准则
突然想起了二叉排序树,这个树中的元素的位置和插入的次序还是有关系的。
迭代器:具有遍历复杂数据结构的能力,其下层的运作机制取决于其所遍历的数据结构。因此每一种容器都要有其相应的迭代器。事实上每种容器都将其迭代器以嵌套的形式定义与内部(使用typename)。因此各种迭代器的接口相同,型别却不同。è泛型设计的概念:所有的操作使用相同的接口,但是他们的型别不同。
一般的情况下使用的是++Iter,这样可以提高效率。
对于序列化容器使用的PushBack()和PushFront()函数,对于关联式的容器而言,毫无意义。想一想为什么
对于Pair类型的数据,必须将其取出,方法是:(*pos).first或者是pos->first
生成pair有三种方法是?
Map是以Key(Key/value)值进行排序的
在Map中索引可以不对应任何的元素,没有的话,将导致插入!,但是MutiMap就不是
MutiMap不允许使用下标【】操作符
迭代器的分类:
1) 双向迭代器 ++ -- list map MutiMap set MutiSet
2) 随机存取迭代器(像一个指针): 增加减少一个偏移量,distance(Iter1,Iter2)<或者>操作符,也就是相对关系Vector Deque Strings
STL中的算法一般是全局函数
使用算法来处理的是一个或者是多个区间中的元素
调用者保证区间的有效性是调用者的责任,如何保证区间的有效性成为一个问题,方法:多次判定(If—else嵌套)、注意考虑:双向迭代器和随机访问迭代器,使用仿函数Compose_f_gx_hx等
注意:如果使用某个算法处理多个区间,那么当你调用它时,务必保证第二个区间所拥有的元素的个数,至少和第一个区间相同。或者使用相应的Iterator进行操作(Insert Iterator)
关联性容器不可能当做覆写型算法的操作目标!
区间是指的是:半开区间
迭代器的适配器
三种
1) Insert Iterator(back_inserter(container)、front_inserter(container)、inserter(container,pos))
2) Stream Iterator
3) Reverse Iterator
其中流迭代器
Istream_iterator<类型>(输入流)//从指定的输入流中输入数据到指定的类型中
Istream_iterator<类型>()调用istream iterators的default构造函数,产生一个代表”流结束符号”的迭代器,他代表的意义是:你不能在读取任何东西
上面的这两个很有用
更易型算法:会删除或者重排或者修改元素的算法
注意remove算法将产生逻辑终点,真正的删除应该使用的是erase方法
注意迭代器自己对于自己所属的容器一无所知,他只不过是容器中某一位置的抽象的概念而已。任何以迭代器访问容器的算法,都不能透过迭代器调用容器类别所提供的任何的成员函数
禁止在关联型容器上使用更易型的算法,但是容器自身可使用相应的成员函数进行相关的操作。
优先使用成员函数è获得高效率
关键字typename:被用来作为类型之前的标示符号
注意他有一个必要条件,特别在用作模版的时候
仿函数(Functor Function Objects)类似函数的对象,任何东西只要行为像函数,他就是一个函数
Class
{
Public:
Return-Value operator()(arguments)const;
}
算法使用暂存对象op(一个函数),针对每一个元素调用op(*Inter)
分成两种case:
1) 一般的函数使用op(*Inter)进行调用
2) 仿函数使用ClassName::operator()(*act)进行调用
可以使用构造函数,传递任意的参数,注意上面那个*act是对应的容器中的元素,而调用的时候传递的arguments,是通过构造函数传递的。
使用仿函数的优点是 三点
系统预先定义好的仿函数
函数适配器:将系统预先定义好的仿函数和其他的数值组合在一起,用于使用特殊情况,主要是传递参数
例如Bind2nd
仿函数Mem_fun_ref用来调用相应元素的成员函数,牛!
STL只支持Value语义,不支持Reference语义,如果想使用相应的Reference语义,请使用指针