说起STL(标准模板库),相信了解C++的都不会陌生吧^_^。LZ是从大三开始学习C++(ps:不是科班出身),并慢慢接触使用STL的,在学校中使用STL比较多的情况是写数据结构代码,使用STL实现数据结构代码(我的数据结构源码),使我们专注于考虑算法思想,不拘泥于底层代码实现。
这里LZ不讲STL的具体知识,只讨论关于STL的学习和使用问题!结合LZ的学习过程,LZ觉得C++的学习(当然,这其中包括的STL)大致路线如下:
- 学习C++基本语法
- 掌握类、继承、多态等概念
- 理解面对对象和泛型编程思想
- 了解并使用STL(标准模板库)
- 阅读STL主要的代码实现,加深对STL的理解
- 探索C++对象模型(这样就理解了类对象的内存布局问题,多态是如何实现的...)
学习C++(包括STL),当然少不了阅读书籍,尤其是经典书籍,参考上面的学习路线,对应的推荐书籍如下:
1/2/3:《C++ Primer》 对C++基本概念、技术、以及现代C++编程风格进行了全面而且权威的阐述,是C++初学者的最佳指南,圣经级书籍。
4/5:《STL源码剖析》 深入分析STL源代码(SGI版本),帮助你加深对STL的理解,以后使用STL就放心大胆了。
6:《深度探索C++对象模型》 专注于C++面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟—虚拟函数和虚拟继承,帮助你理解程序的底层实现,以便写出更高效的代码。
当然,在学习的过程中,可以同时阅读《Effective C++》,帮助你写出更加健壮的C++代码。学习C++以及STL阅读这几本书,其他的C++书籍大可不必再看了。
1、STL是什么
STL(Standard Template Library 标准模板库)是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件,STL现在是C++的一部分。
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):一种用来修饰容器、仿函数、迭代器接口的东西。例如:STL提供的queue 和 stack,虽然看似容器,但其实只能算是一种容器配接器,因为它们的底部完全借助deque,所有操作都由底层的deque供应。改变 functors接口者,称为function adapter;改变 container 接口者,称为container adapter;改变iterator接口者,称为iterator adapter。
- 配置器(allocators):负责空间配置与管理。从实现的角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的class template。
STL六大组件将的交互关系
2、公司实际项目中到底该不该用STL呢
网上关于STL的讨论还是很多的,比如为何某些公司不允许使用STL?STL到底该不该用?...这里结合LZ的实际工作经历,来谈谈STL的使用问题,LZ目前在某华做安防平台开发,项目中就使用了STL,不过项目中使用的大都是STL中容器、迭代器部分,像算法等其他部分很少使用。LZ觉得,在实际项目中使不使用STL,主要看项目的实际需求,根据具体使用场景来取舍。该安防平台主要负责与设备通信、存储设备发送上来的图片和视频、与web端交互等,由于平台接入设备有限,所以不会有很大的并发量,使用STL完全满足要求了。
使用STL,避免了底层数据的封装处理,更专注于业务逻辑实现;但是使用STL可能会产生代码膨胀问题、内存使用效率问题、类型隐式转换问题,这些问题在项目中数据量较大或者项目并发要求比较高就会成为性能瓶颈的,注意,STL容器不是线程安全的,在多线程中使用需要自己实现加锁操作。
3、继续学习C++
学习C++,除了经典书籍外还有另外一个比较重要的资源,那就是开源代码。阅读开源代码,不进可以了解源码规范,还可以深入了解该系统是如何实现的,加深对技术的理解。阅读源码的同时,自己可以尝试造轮子,关于C++,有几个比较经典的源码:
- leveldb:Google出品,遵循Google C++编码规范。作者是Jeff Dean大神。
- libevent:是一个开源的事件驱动库,基于epoll,kqueue等OS提供的基础设施。
- TeamTalk:蘑菇街开源的即时通信软件,有PC、Android、Ios版本,其中Server端是C++实现。
- ...
参考资料
2、《STL源码剖析》第一章节部分