今日份知识分享:c++中STL库的简介及使用说明

作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的。STL不是实验室里的宠儿,也不是程序员桌上的摆设,她的激动人心并非昙花一现。本教程旨在传播和普及STL的基础知识,若能借此机会为STL的推广做些力所能及的事情,到也是件让人愉快的事情。

初识STL:解答一些疑问

一个最关心的问题:什么是STL

“什么是STL?”,假如你对STL还知之甚少,那么我想,你一定很想知道这个问题的答案,坦率地讲,要指望用短短数言将这个问题阐述清楚,也决非易事。因此,如果你在看完本节之后还是觉得似懂非懂,大可不必着急,在阅读了后续内容之后,相信你对STL的认识,将会愈加清晰、准确和完整。不过,上述这番话听起来是否有点像是在为自己糟糕的表达能力开脱罪责呢?:)

不知道你是否有过这样的经历。在你准备着手完成数据结构老师所布置的家庭作业时,或者在你为你所负责的某个软件项目中添加一项新功能时,你发现需要用到一个链表(List)或者是映射表(Map)之类的东西,但是手头并没有现成的代码。于是在你开始正式考虑程序功能之前,手工实现List或者Map是不可避免的。于是……,最终你顺利完成了任务。或许此时,作为一个具有较高素养的程序员的你还不肯罢休(或者是一个喜欢偷懒的优等生:),因为你会想到,如果以后还遇到这样的情况怎么办?没有必要再做一遍同样的事情吧!

如果说上述这种情形每天都在发生,或许有点夸张。但是,如果说整个软件领域里,数十年来确实都在为了一个目标而奋斗–可复用性(reusability),这看起来似乎并不夸张。从最早的面向过程的函数库,到面向对象的程序设计思想,到各种组件技术(如:COM、EJB),到设计模式(design pattern)等等。而STL也在做着类似的事情,同时在它背后蕴涵着一种新的程序设计思想–泛型化设计(generic programming)。

继续上面提到的那个例子,假如你把List或者map完好的保留了下来,正在暗自得意。且慢,如果下一回的List里放的不是浮点数而是整数呢?如果你所实现的Map在效率上总是令你不太满意并且有时还会出些bug呢?你该如何面对这些问题?使用STL是一个不错的选择,确实如此,STL可以漂亮地解决上面提到的这些问题,尽管你还可以寻求其他方法。

说了半天,到底STL是什么东西呢?

STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。这种现象有些类似于Microsoft Visual C++中的MFC(Microsoft Foundation Class Library),或者是Borland C++ Builder中的VCL(Visual Component Library),对于此二者,大家一定不会陌生吧。

从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming),引入了诸多新的名词,比如像需求(requirements),概念(concept),模型(model),容器(container),算法(algorithmn),迭代子(iterator)等。与OOP(object-oriented programming)中的多态(polymorphism)一样,泛型也是一种软件的复用技术。

从实现层次看,整个STL是以一种类型参数化(type parameterized)的方式实现的,这种方式基于一个在早先C++标准中没有出现的语言特性–模板(template)。如果查阅任何一个版本的STL源代码,你就会发现,模板作为构成整个STL的基石是一件千真万确的事情。除此之外,还有许多C++的新特性为STL的实现提供了方便。

一、什么时候用STL

如果,有的时候,你要在程序中用到堆(heap)、栈(stack)、队列(queue)、链表(list)等一些基本的算法,而你又实在不想自己去实现数据结构教科书中那些繁琐的算法,那么你就可以考虑使用STL。

另外,STL作为一种标准,便于交流,掌握它,一方面可以让你写的程序,易于让别人理解,另一方面你也能够比较容易地理解别人写的程序。

二、容器模板的使用

大致有下面6个步骤:

​ 1.添加相应的头文件(如 #include <list> )( *\*注意,没有 .h**** )

​ 2.添加std命名空间(用 using namespace std; )

​ 3.赋予模板具体的使用类型(如 typedef list<string> LISTSTR; )

​ 4.实例化模板(如 LISTSTR test; )

​ 5.实例化游标(如 LISTSTR::iterator i; )

​ 6.通过迭代器对象访问模板对象,例如

​ // 逐个输出链表test中的元素
​ for ( i = test.begin(); i != test.end(); ++i )
​ cout << *i << “ “;

三、容器模板中的常用函数

assign() 赋值

empty() 容器为空则返回非0值

erase() 删除指定位置或指定范围内的元素

push_front() 从容器头部插入元素

push_back() 从容器尾部插入元素

pop_front() 删除第一个元素

pop_back() 删除最后一个元素

back() 返回最后一个元素的引用

front() 返回第一个元素的引用

begin() 返回指向第一个元素的游标 (与迭代器配合使用)

end() 返回指向最后一个元素的后一个位置的游标 (最后1个元素再加1) (与迭代器配合使用)