一、STL 总体架构
STL 是 C++ 标准库的核心组成部分。它不是单一的概念,而是由五个相互协作的组件组成的完整体系。这五个组件就像一个精密的钟表,每个部件都有自己的职责,协同工作。
想象一下这五个组件的关系:
- 容器是各种盒子(书架、衣柜、抽屉)
- 算法是操作方法(怎么放、怎么取、怎么整理)
- 迭代器是手或工具(连接你和盒子的桥梁)
- 仿函数是智能工具(带特殊功能的夹子、剪刀)
C++ STL 的五大核心组件:容器、算法、迭代器、仿函数和适配器。容器负责数据存储,如 vector、list 等;算法提供通用操作方法,如排序、查找;迭代器作为桥梁连接容器与算法;仿函数实现可携带状态的函数对象;适配器用于转换接口。文章详细阐述了各组件的分类、特性及协同工作流程,并通过示例展示了如何使用 STL 进行数据管理和处理,强调了组件间的松耦合设计思想。
STL 是 C++ 标准库的核心组成部分。它不是单一的概念,而是由五个相互协作的组件组成的完整体系。这五个组件就像一个精密的钟表,每个部件都有自己的职责,协同工作。
想象一下这五个组件的关系:
容器就是装数据的各种'容器',就像现实中的数组、链表、树、哈希表等数据结构的模板实现。
第一层:按存储方式分
vector:动态数组(像可以自动扩容的货架)deque:双端队列(像两头的传送带)list:双向链表(像一串珍珠项链)forward_list:单向链表(只能向前走的项链)array:固定数组(固定大小的储物格)set:唯一键集合(不允许重复的集合)multiset:可重复键集合(允许重复的集合)map:键值对映射(像电话簿:名字→号码)multimap:可重复键的映射(同名可以有多个号码)unordered_set:无序唯一集合unordered_map:无序键值映射stack:栈(后进先出,像叠盘子)queue:队列(先进先出,像排队)priority_queue:优先队列(按优先级出队,像医院急诊)关键点 1:模板
所有容器都是类模板,可以存储任何类型:
vector<int> // 存 int
vector<string> // 存 string
vector<vector<int>> // 存 vector(二维数组)
关键点 2:内存管理
关键点 3:接口统一
所有容器都提供类似的接口:
size():元素个数empty():是否为空begin()/end():迭代器clear():清空算法是操作数据的通用方法,就像一本说明书,告诉你如何对数据进行排序、查找、复制、删除等操作。
关键特点 1:通用性
算法不关心具体容器类型,只通过迭代器操作数据:
// 同样的 sort 算法,可以对 vector、deque、array 等排序
sort(vector.begin(), vector.end());
sort(deque.begin(), deque.end());
关键特点 2:函数模板
算法都是函数模板,可以处理各种数据类型:
sort(int_vector.begin(), int_vector.end()); // 排序 int
sort(string_vector.begin(), string_vector.end()); // 排序 string
关键特点 3:迭代器依赖
算法通过迭代器访问容器元素,不直接操作容器本身。
常用算法类别:
sort:快速排序stable_sort:稳定排序(相等元素保持原顺序)partial_sort:部分排序find:线性查找binary_search:二分查找(要求已排序)lower_bound/upper_bound:边界查找copy:复制fill:填充replace:替换remove:删除(实际是移动,需要配合 erase)accumulate:累加inner_product:内积adjacent_difference:相邻差set_union:并集set_intersection:交集set_difference:差集重要概念:算法复杂度
sort() // O(n log n) - 快排
find() // O(n) - 线性查找
binary_search() // O(log n) - 二分查找
迭代器是连接容器和算法的桥梁,它像是一个智能指针,知道如何在容器中移动并访问元素。
桥梁作用:
text
容器(数据存储) ←→ 迭代器(访问接口) ←→ 算法(操作逻辑)
关键能力:
理解层次:从简单到复杂
**重要警告:**某些操作会使迭代器失效!
vector 的典型问题:
vector<int> v = {1, 2, 3};
auto it = v.begin() + 1; // 指向 2
v.push_back(4); // 可能导致重新分配内存
// 此时 it 失效!不能再使用
不同容器的失效规则:
仿函数是行为像函数的对象,它实际上是一个重载了 () 运算符的类对象。
传统函数指针的局限性:
仿函数的优势:
简单示例:
// 定义一个仿函数类
struct AddValue {
int value;
AddValue(int v) : value(v) {}
// 重载 () 运算符
int operator()(int x) const {
return x + value;
}
};
// 使用
AddValue add5(5);
int result = add5(10); // 调用 add5.operator()(10),返回 15
算术运算:
plus<T>:加法minus<T>:减法multiplies<T>:乘法divides<T>:除法modulus<T>:取模negate<T>:取负比较运算:
equal_to<T>:等于not_equal_to<T>:不等于greater<T>:大于less<T>:小于greater_equal<T>:大于等于less_equal<T>:小于等于逻辑运算:
logical_and<T>:与logical_or<T>:或logical_not<T>:非使用示例:
// 使用 greater 进行降序排序
sort(v.begin(), v.end(), greater<int>());
C++11 引入 lambda 表达式,很多情况下替代仿函数:
// 传统仿函数
struct Compare {
bool operator()(int a, int b) {
return a > b;
}
};
sort(v.begin(), v.end(), Compare());
// Lambda 表达式(更简洁)
sort(v.begin(), v.end(), [](int a, int b) {
return a > b;
});
适配器是接口转换器,它修改现有组件的接口,使其适应新的需求。
1. 容器适配器
stack:基于 deque/vector/list,提供栈接口queue:基于 deque/list,提供队列接口priority_queue:基于 vector,提供优先队列接口示例:stack 的实现原理
// stack 内部包含一个 deque
template<typename T, typename Container = deque<T>>
class stack {
private:
Container c; // 底层容器
public:
void push(const T& value) {
c.push_back(value);
}
void pop() {
c.pop_back();
}
T& top() {
return c.back();
}
// ... 其他操作
};
2. 迭代器适配器
reverse_iterator:反向迭代器insert_iterator:插入迭代器stream_iterator:流迭代器示例:反向迭代器
vector<int> v = {1, 2, 3};
// 反向遍历
for (auto rit = v.rbegin(); rit != v.rend(); ++rit) {
cout << *rit << " "; // 输出:3 2 1
}
3. 函数适配器
binder1st/binder2nd:绑定参数(C++11 前)not1/not2:逻辑取反示例:bind 适配器(C++11)
// 绑定函数的第二个参数
auto add = [](int a, int b) {
return a + b;
};
auto add5 = std::bind(add, std::placeholders::_1, 5);
cout << add5(10); // 输出 15
// 1. 容器:创建数据存储
vector<int> numbers = {5, 2, 8, 1, 9};
// 2. 迭代器:提供访问接口
auto begin = numbers.begin(); // 获取起始位置
auto end = numbers.end(); // 获取结束位置
// 3. 算法:执行排序操作
// 内部使用迭代器访问元素
sort(begin, end);
// 可选:使用仿函数改变排序行为
sort(begin, end, greater<int>()); // 降序排序
// 4. 适配器:改变访问方式
// 反向输出
copy(numbers.rbegin(), numbers.rend(), ostream_iterator<int>(cout, " "));
整个过程的数据流:
text
数据 → 存入容器 → 迭代器访问 → 算法处理 → 结果输出
关键设计思想:
完整比喻:图书馆系统
vector:一排可以扩展的书架list:用链条连接的书格map:按书名排序的目录柜set:不允许重复的珍本书架sort:按某种规则整理书籍find:查找特定书籍copy:复印书籍remove:下架旧书整个系统工作流程:
管理员(算法)使用扫码枪(迭代器)按照特定规则(仿函数)在书架(容器)上操作,通过特殊设备(适配器)满足特殊需求。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online