首页 理论教育 大道至简:C++ STL(标准模板库)精解

大道至简:C++ STL(标准模板库)精解

时间:2023-10-25 理论教育 版权反馈
【摘要】:STL中的所有算法都是基于模板实现的。STL定义了5种类型的指示器,并根据其使用方法予以命名。为提高效率,STL定义了仿函数这种概念。例如,5.内存配置器和配接器STL包括底层的内存分配和释放。配接器对于STL技术来说非常重要。例1-30例1-30执行结果如图1-16所示。

大道至简:C++ STL(标准模板库)精解

STL是C++通用库,由迭代器、算法容器、仿函数、配接器和配置器(即内存配置器)组成。

1.容器

STL包含诸多容器类。容器类是可以包含其他对象的类,就像数组和队列堆栈数据结构包含整数、小数、类等数据成员一样。STL可以包含常见的向量类、链表类、双向队列类、集合类、图类等。每个类都是一种模板。这些模板可以包含各种类型的对象。下述代码是常用的vector赋值方法:

978-7-111-51399-5-Chapter01-121.jpg

下述代码采用map容器进行二维元素的管理:

978-7-111-51399-5-Chapter01-122.jpg

map类似于二维数组,但比二维数组灵活得多。

目前,STL中已经提供的容器主要如下。

•vector<T>。一种向量。

•list<T>。一个双向链表容器,完成了标准C++数据结构中链表的所有功能。

•queue<T>。一种队列容器,完成了标准C++数据结构中队列的所有功能。

•stack<T>。一种栈容器,完成了标准C++数据结构中栈的所有功能。

•deque<T>。双端队列容器,完成了标准C++数据结构中栈的所有功能。

•priority__queue<T>。一种按值排序的队列容器。

•set<T>。一种集合容器。

•multiset<T>。一种允许出现重复元素的集合容器。

•map<key,val>。一种关联数组容器。

•multimap<key,val>。一种允许出现重复key值的关联数组容器。

以上容器设计高效,还提供了接口程序员可以在任何适当的地方使用它们。

容器可以分为序列式容器和关联式容器两大类。序列式容器主要有vector、list和de- que;关联式容器包括set、map、multiset和multimap等容器模板类。

2.算法

STL提供了非常多的数据结构算法。这些算法在命名空间std的范围内定义,通过包含头文件<algorithm>来获得使用权。

常见的部分算法如下。

978-7-111-51399-5-Chapter01-123.jpg

978-7-111-51399-5-Chapter01-124.jpg

STL中的所有算法都是基于模板实现的。(www.xing528.com)

3.迭代器

通俗来讲,迭代器就是指示器。迭代器技术能够使程序非常快捷地实现对STL容器中内容的反复访问。反复访问意味着一次可以访问一个或多个元素。迭代器为访问容器提供了通用的方法,类似于C++的指针。当参数化类型是C++内部类型时,迭代器即C++指针。STL定义了5种类型的指示器,并根据其使用方法予以命名。每种容器都支持某种类别的迭代器。常见的迭代器包括输入、输出、前向、双向和随机接入等类别。

输入迭代器主要用于为程序中需要的数据源提供输入接口,此处的数据源一般指容器、数据流等。输入迭代器只能从一个序列中读取数值。该迭代器可以被修改和被引用。

输出迭代器主要用于输出程序中已经得到的数据结果(容器,数据流)。输出迭代器只能向一个序列写入数据。该迭代器也可以被修改和被引用。

双向迭代器既可以用来读又可以用来写,它与前向迭代器相类似。双向迭代器可以同时进行前向和后向元素操作。所有STL容器都提供了双向迭代器功能,这既有利于数据的写入和读出,又有利于提供更加灵活的数据操作。

有的容器甚至提供了随机接入迭代器。随机接入迭代器可以通过跳跃的方式访问容器中的任意数据,使数据的访问非常灵活。随机访问迭代器具有双向迭代器的所有功能,是功能最强大的迭代器类型。

迭代器的诞生使算法和容器分离成为可能。算法是模板,其类型依赖于迭代器,不会局限于单一容器。不同的STL算法需要不同类型的迭代器来实现相应的功能。因为不同类型的STL容器支持不同类型的迭代器,所以不能对所有容器使用相同的算法。

4.仿函数

理解了算法、迭代器、容器之后,读者已经熟悉了STL的大部分内容。STL还有两个最重要的内容:仿函数和内存配置器。本小节简单介绍仿函数,下一小节介绍内存分配器。

STL包含了大量仿函数。仿函数可以理解为函数的一般形式。对于编程来说,仿函数非常重要,并有几种约束。在C++标准中,函数调用一般使用指针,当需要调用函数时,只需要提供函数的地址即可。例如,

978-7-111-51399-5-Chapter01-125.jpg

上述代码定义了一个cmp()函数,当需要调用此函数时,只需提供函数的地址即可。例如,

978-7-111-51399-5-Chapter01-126.jpg

此方法的最大缺陷是效率低。为提高效率,STL定义了仿函数这种概念。下述代码定义了一个仿函数,其特征是使用operator实现定义。

978-7-111-51399-5-Chapter01-127.jpg

978-7-111-51399-5-Chapter01-128.jpg

通过运算符定义显著提高效率。例如,

978-7-111-51399-5-Chapter01-129.jpg

5.内存配置器和配接器

STL包括底层的内存分配和释放。内存配置器非常少见,在此可以忽略,在后面章节专门介绍。配接器可以实现不同类之间的数据转换。最常用的配接器有istream_iterator,它提供了函数复制的接口。配接器对于STL技术来说非常重要。STL提供了3种容器配接器:stack<Container>,queue<Container>,和deque<Container>。

例1-30

978-7-111-51399-5-Chapter01-130.jpg

例1-30执行结果如图1-16所示。

978-7-111-51399-5-Chapter01-131.jpg

图1-16 例1-30的执行效果

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈