(转)STL:历史与组件速览

——STL的优点就不罗嗦了,对一个C++开发人员来讲,不熟悉STL是无论如何都说不过去的,这不需要什么借口。侯捷老师的大作《STL源码剖析》确实是深入学习STL的绝佳教材,于是决定好好研读一下这本书,并将所学记录于blog上,作为一个学习笔记,说不定还能遇到不少同道中人共同学习。
如果能更多的了解STL的机制,就可以不仅更加纯熟的应用,掌握一个开发的利器,更能学习其设计思想而加以应用,使自己的功力更进一层。
一 STL简简史
C++由Bjarne Stroustrup创立于1979年,而就在那一年Alexander Stepanov创立了STL,大师的眼界总是这么超前哪;直到1993年9月STL才开始了进入C++标准库的历程,并于1998年9月STL终于正式进入C++标准,成为C++程式库的一大派系。就连C++程式库原有的stream和string也都用template重新写过,可见其影响力(经常看到网上对string的指责,应该和后入STL也有点关系吧)。
STL有不同的版本,包括HP的版本(所有STL之源),P.J.Plauger版本(Visual C++采用的就是这个),Rouge Wave版本(C++ Builder采用)和SGI版本。侯捷老师推荐的是SGI的版本,可读性更高,《STL源码剖析》也是以其为蓝本。
二 STL 六大组件
学习使用STL是相对简单的,然而如果要深入STL的底层,那里却是海底的冰山,其复杂性是不言而喻的,哦,希望不要把人吓倒,好消息是:这也是一座充满惊喜的宝库。
先来看看这六大组件吧,这里先有个基本的概念,等用到它们的时候再详细探究到底是怎么回事吧。
1. 容器(containers),STL里面有很多容器,比如list, vector, deque, ma
p,这都是比较常用的,容器是用来组织存放数据的。你甚至可以把int A[20]声明的数组看作是一个整型容器,它以线性相关的方式存储了20个整型数据。STL的容器是一种class template。
2. 演算法(algorithms),比如sort, search等各种常用的算法,STL中的演算法相当于function template。
3. 迭代器(iterators), 有了容器就需要知道如何访问容器里面的元素,就像一个数组可以使用索引访问一样,迭代器就是访问容器的接口,而又不会出卖容器内部的数据组织方式。所有的STL容器都必须附带自己的迭代器——毕竟只有容器设计者自己才知道如何访问容器的元素。
4. 仿函式(functors),防函式是一种重载了operator()的class或者class template,容易让人感到困惑的东西。
5. 适配器(adapters),一种包装了容器或者防函式的东西,只是根据需要提供必须的接口,而不是把提供原来的所有接口,想想DesignPattern中的Adapter模式吧,是一样的了。比如STL中的queue和stack虽然很像容器,但是实际上只是适配器,因为其底层完全重用了deque。
6. 配置器(allocators),负责空间分配管理,在STL中配置器也是一个class。将配置器独立成一个组件的好处就是,你可以根据需要定制自己的配置器,这样既可以利用S
TL的便利性,又可以满足效率的要求。
图1-1显示了六大组件之间的相互关系。
[img]https://p-blog.csdn.net/images/p_blog_csdn_net/sparkliang/EntryImages/20081229/STL%20six%20components.JPG[/img]
三 Function call运算子(operator () )速写
函数调用算子(C++语法中的())也可以被重载,如果一个类重载了(),它就成了一个仿函式。
在C语言中,如果需要就将一个函数作为参数传递,只能通过指针的方式,比如常用的qsort(函数:
int cmp(const void *a, const void*b){ … }
A a[20];

qsort(a, 20, sizeof(A), cmp);

而在STL中,这些是通过防函式完成的,防函式具有可适配性(adaptability)——也就是可以将某些条件加于其上而改变其状态,这是函数指针不具有的,和上面对应的例子如下:
template<class T>
class CCmp{
public: // 重载了(),类CCmp就成了一个防函式
int operator()(const T &a, const T &b){ … }
};
// 声明防函式对象
CCmp<A> cmpA;
// 使用防函式就像使用函数一样
if(cmpA(a0, a1) < 0){
cout<<”a0 < a1”<<endl;
}
// 还可以生成防函式的临时对象,同时使用
if(CCmp<A>()(a0, a1) < 0){
cout<<”a0 < a1”<<endl;
}
CCmp<T>已经很接近STL的防函式了,唯一缺乏的就是上面提到的可适配性。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值