C++学习笔记(二十三)——STL标准库
一、STL(Standard Template Library)
STL(标准模板库) 是 C++ 标准库 的重要组成部分,提供了通用的数据结构和算法,使 C++ 具备高效、泛型、可复用的编程能力。
STL 主要由六大组件组成:
组件 | 作用 |
---|---|
容器(Containers) | 存储和管理数据(如 vector , list , map ) |
算法(Algorithms) | 处理数据(如 sort() , find() , for_each() ) |
迭代器(Iterators) | 访问容器元素(如 begin() , end() ) |
仿函数(Functors) | 使算法更灵活(如 greater<int>() ) |
适配器(Adapters) | 修改容器/函数对象行为(如 stack , queue ) |
空间配置器(Allocators) | 控制内存管理(一般默认) |
特点:
- 高效 —— 采用模板,提高性能。
- 通用 —— 适用于多种类型。
- 安全 —— 内置边界检查。
STL 是 C++ 强大的核心,广泛应用于数据处理、搜索、排序等场景。
二、容器(Containers)
(1) 序列式容器(Sequence Containers)
作用:存储有序元素,支持索引、插入、删除等操作。
容器 | 特点 | 适用场景 |
---|---|---|
vector<T> | 动态数组,可自动扩展 | 随机访问,元素较少 |
list<T> | 双向链表,插入/删除快 | 频繁插入/删除 |
deque<T> | 双端队列,两端操作快 | 两端插入/删除 |
array<T, N> | 固定大小数组 | 替代 C 数组 |
(2) 关联式容器(Associative Containers)
作用:存储键值对(key-value),自动排序。
容器 | 特点 | 适用场景 |
---|---|---|
map<K, V> | 有序字典(红黑树) | 键值映射,快速查找 |
set<T> | 有序集合 | 去重,排序 |
multimap<K, V> | 允许重复键 | 多对多映射 |
multiset<T> | 允许重复元素 | 有序统计 |
(3) 无序容器(Unordered Containers)
作用:基于哈希表,无序存储,查找快。
容器 | 特点 |
---|---|
unordered_map<K, V> | 无序字典,哈希查找快 |
unordered_set<T> | 无序集合 |
unordered_multimap<K, V> | 允许重复键 |
unordered_multiset<T> | 允许重复元素 |
三、算法(Algorithms)
作用:
STL 提供了 80+ 算法,如排序、搜索、变换等。
算法 | 作用 |
---|---|
sort() | 排序 |
find() | 查找 |
count() | 计数 |
reverse() | 反转 |
accumulate() | 求和(需 <numeric> ) |
for_each() | 遍历 |
示例——排序 vector
:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm> // sort()
int main() {
vector<int> v = { 40, 10, 30, 20 };
sort(v.begin(), v.end()); // 默认升序
for (int x : v)
{
cout << x << " ";
}
cout << endl;
system("pause");
return 0;
}
降序排序时,可以使用:
#include <functional>
sort(v.begin(), v.end(), greater<int>());
四、迭代器(Iterators)
作用:
用于遍历 STL 容器,类似指针。
迭代器类型 | 作用 |
---|---|
begin() | 指向首元素 |
end() | 指向末尾之后(尾后迭代器) |
rbegin(), rend() | 反向迭代 |
advance(it, n) | 移动迭代器 n 个位置(正数向后,负数向前) |
next(it), prev(it) | 获取前/后迭代器 |
示例——使用迭代器遍历 vector
:
#include <iostream>
using namespace std;
#include <vector>
int main() {
vector<int> v = { 10, 20, 30, 40 };
// 使用迭代器遍历
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
注意:
- 使用
auto
让代码更简洁:for (auto it = v.begin(); it != v.end(); ++it) { cout << *it << " "; }
- 使用
range-based for
直接遍历:for (int x : v) { cout << x << " "; }
end()
返回的迭代器,指向容器末尾元素的下一个位置。
五、仿函数(Functors)
作用:
仿函数(函数对象)是重载operator()
的类,可用于 sort()
。
示例——自定义比较函数:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
// 定义仿函数,降序
class Desc {
public:
bool operator()(int a, int b)
{
return a > b;
}
};
int main() {
vector<int> v = { 10, 30, 20 };
sort(v.begin(), v.end(), Desc()); // 使用仿函数排序
for (int x : v)
{
cout << x << " ";
}
cout << endl;
system("pause");
return 0;
}
注意:
适用于排序、过滤等场景。
六、适配器(Adapters)
作用:
适配器用于修改容器行为,如 stack
、queue
。
适配器 | 底层结构 | 特点 |
---|---|---|
stack<T> | deque | LIFO(后进先出) |
queue<T> | deque | FIFO(先进先出) |
priority_queue<T> | vector | 最大堆 |
示例——使用 stack
:
#include <iostream>
using namespace std;
#include <stack>
int main() {
stack<int> s;
s.push(10);
s.push(20);
s.push(30);
cout << s.top() << endl; // 30
s.pop();
cout << s.top() << endl; // 20
system("pause");
return 0;
}
注意:
适用于 LIFO(后进先出)结构,如浏览器前进/后退、撤销操作等。
七、空间配置器(Allocators)
作用:
STL 空间配置器(Allocator) 是 C++ 标准模板库(STL)中用于管理动态内存分配的组件,可以优化性能,避免频繁 malloc/free
带来的开销。
STL 容器(如 vector
、deque
、list
等)默认使用std::allocator<T>
来分配和释放内存。
std::allocator<T>
提供了一些基础的内存管理方法:
方法 | 作用 |
---|---|
allocate(n) | 分配 n 个 T 类型对象的内存 |
deallocate(ptr, n) | 释放 n 个 T 类型对象的内存 |
construct(ptr, args...) | 在 ptr 指向的内存上构造对象 |
destroy(ptr) | 调用 ptr 指向对象的析构函数 |
示例1——使用STL 默认空间配置器:
#include <iostream>
using namespace std;
#include <vector>
#include <memory> // 包含 allocator 头文件
int main() {
vector<int, allocator<int>> vec; // 指定默认 allocator
vec.push_back(10);
vec.push_back(20);
cout << vec[0] << " " << vec[1] << endl;
system("pause");
return 0;
}
注意:
STL 容器默认使用std::allocator<T>
,但可以替换为自定义 Allocator。
示例2——使用 std::allocator 手动管理内存:
#include <iostream>
using namespace std;
#include <memory> // 包含 allocator
int main() {
allocator<int> alloc; // 创建 allocator
int* p = alloc.allocate(3); // 分配 3 个 int 空间
alloc.construct(p, 10); // 构造第一个元素 10
alloc.construct(p + 1, 20); // 构造第二个元素 20
alloc.construct(p + 2, 30); // 构造第三个元素 30
cout << p[0] << " " << p[1] << " " << p[2] << endl;
alloc.destroy(p); // 销毁第一个元素
alloc.destroy(p + 1); // 销毁第二个元素
alloc.destroy(p + 2); // 销毁第三个元素
alloc.deallocate(p, 3); // 释放内存
system("pause");
return 0;
}
注意:
手动 allocate() 申请空间,construct() 进行构造,destroy() 进行析构,最后 deallocate() 释放内存。