STL概念及组件介绍
究其根本,STL是一些容器的集合,这些容器有list、vector、set、map等,其也是算法和其他组件的集合,就是厉害的人将一些常用的算法封装成函数库,供人们使用,这些模板类和函数可实现多种流行和常用的算法和数据结构。C++标准模板库核心包括以下三个组件:
组件 | 描述 |
---|---|
容器(Containers) | 容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。 |
算法(Algorithms) | 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。 |
迭代器(iterators) | 迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。 |
STL基本结构
STL主要由迭代器、算法、容器、仿函数、内存配置器和配接器六大部分构成。
容器
STL包含很多容器类,容器类是可包含其他对象的类,就像数组和队列堆栈等数据结构包含整数、小数、类等数据成员一样,常见有向量类、链表类、双向队列类、集合类、图类等,每个类都是一种模板,可以包含各种类型的对象。
目前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和deque;关联式容器包括set、map、multiset和multimap等容器模板类。
算法
STL提供了非常多的数据结构算法,在标准C++中的命名空间std的范围内定义由头文件< algorithm >
,< numeric >
和< functional >
组成,< algorithm >
是所有STL头文件中最大的一个,它是由一堆模板函数构成,可认为每个函数很大程度上相互独立,具体内容,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等可查看C++常用算法,STL常用算法(排序、合并、搜索和分区)。
迭代器
迭代器通俗来说就是指示器,它能使程序非常快捷地实现对STL容器中内容的反复访问,即一次可访问一个或多个元素,其的作用是在STL中将算法和容器联系起来,相当于抽象间接层,几乎所有的算法都是通过迭代器存取元素序列进行工作,每个容器定义了本身专有的迭代器。STL定义了五种类型指示器,常见的有输入、输出、前向、双向和随机接入等类别:
- 输入迭代器:用于程序中需要数据源(容器、数据流)提供输入接口,输入迭代器只能从一个序列中读取数值,可被修改和引用;
- 输出迭代器:用于输出程序中得到数据结果(容器、数据流),输出迭代器只能像一个序列写入数据,也可被修改和引用;
- 双向迭代器:即可用来读又可用来写与前向迭代器类似,其可同时进项前向和后向的元素操作,所有STL容器都提供了双向迭代器的功能,有利于写入和读出操作;
- 随机接入迭代器:可通过跳跃的方式访问容器的任意数据,访问数据的操作很灵活,包含双向迭代器的功能,是功能最强大的迭代器类型。
迭代器部分主要由头文件< utility >
,< iterator >
和< memory >
组成,迭代器的产生使得算法和容器得以分离,不同的STL算法需要不同类型的迭代器实现相应功能。
其中仿函数、内存配置器和配接器不在这里做详细介绍。
STL使用实例
下面通过实例演示向量容器(vector),与数组十分相似,唯一不同的就是向量在扩展大小时会自动处理存储需求:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// 创建一个向量存储 int
vector<int> vec;
int i;
// 显示 vec 的原始大小
cout << "vector size = " << vec.size() << endl;
// 推入 5 个值到向量中
for(i = 0; i < 5; i++){
vec.push_back(i);
}
// 显示 vec 扩展后的大小
cout << "extended vector size = " << vec.size() << endl;
// 访问向量中的 5 个值
for(i = 0; i < 5; i++){
cout << "value of vec [" << i << "] = " << vec[i] << endl;
}
// 使用迭代器 iterator 访问值
vector<int>::iterator v = vec.begin();
while( v != vec.end()) {
cout << "value of v = " << *v << endl;
v++;
}
return 0;
}
显示结果如下:
在上面程序中所用到的函数:
push_back( )
成员函数在向量的末尾插入值,如果有必要会扩展向量的大小;size( )
函数显示向量的大小;begin( )
函数返回一个指向向量开头的迭代器;end( )
函数返回一个指向向量末尾的迭代器。
后面的会对每个容器的使用方法及函数展开讨论。
参考文章:C++ STL 教程