C++教程-C++ STL (Standard Template Library)教程
C++ STL (Standard Template Library)教程
C++ STL(标准模板库)是C++标准库的一部分,提供了一组通用的模板类和函数,用于实现不同的数据结构,如数组、链表、树等。
以下是STL中的容器,提供了有关所有容器的详细信息,包括头文件和与它们关联的迭代器类型:
容器 | 描述 | 头文件 |
---|---|---|
vector | vector是一个创建动态数组的类,允许在后端进行插入和删除操作。 | <vector> 随机访问 |
list | list是序列容器,允许从任意位置进行插入和删除操作。 | <list> 双向访问 |
deque | deque是双端队列,允许从两端进行插入和删除操作。 | <deque> 随机访问 |
set | set是用于存储唯一集合的关联容器。 | <set> 双向访问 |
multiset | multiset是用于存储非唯一集合的关联容器。 | <set> 双向访问 |
map | map是用于存储唯一键值对的关联容器,即每个键与一个值关联(一对一映射)。 | <map> 双向访问 |
multimap | multimap是用于存储键值对的关联容器,一个键可以与多个值关联。 | <map> 双向访问 |
stack | stack 栈,遵循后进先出(LIFO)原则。 | <stack> 无迭代器 |
queue | 队列,遵循先进先出(FIFO)原则。 | <queue> 无迭代器 |
priority_queue | 优先队列,始终将最高优先级的元素排在前面。 | <queue> 无迭代器 |
容器分类:
- 序列容器
- 关联容器
- 派生容器
注意:每个容器类都包含一组函数,可用于操作内容。
迭代器
- 迭代器是类似指针的实体,用于访问容器中的各个元素。
- 迭代器顺序地从一个元素移动到另一个元素。这个过程称为遍历容器。
- 迭代器主要包含两个函数:
begin():成员函数begin()返回指向容器的第一个元素的迭代器。 end():成员函数end()返回指向容器尾后位置的迭代器。
迭代器类别
迭代器主要分为五个类别:
输入迭代器:
- 输入迭代器是允许程序从容器中读取值的迭代器。 对输入迭代器进行解引用允许从容器中读取一个值,但不会改变该值。
- 输入迭代器是单向迭代器。
- 输入迭代器可以增加,但不能减少。
输出迭代器:
- 输出迭代器类似于输入迭代器,但允许程序修改容器的值,但不能读取。
- 它是单向迭代器。 它是只写迭代器。
前向迭代器:
- 前向迭代器使用++运算符在容器中导航。
- 前向迭代器逐个元素遍历容器。
双向迭代器:
- 双向迭代器类似于前向迭代器,但也可以向后移动。
- 它是双向迭代器。
- 它可以增加和减少。
随机访问迭代器:
- 随机访问迭代器用于访问容器的随机元素。
- 随机访问迭代器具有双向迭代器的所有功能,并且还具有指针加法的额外功能。通过使用指针加法操作,我们可以访问容器的随机元素。
迭代器支持的操作
迭代器 | 元素访问 | 读取 | 写入 | 递增操作 | 比较 |
---|---|---|---|---|---|
输入迭代器 | -> | v = *p | ++ | ==,!= | |
输出迭代器 | *p = v | ++ | |||
前向迭代器 | -> | v = *p | *p = v | ++ | ==,!= |
双向迭代器 | -> | v = *p | *p = v | ++,-- | ==,!= |
随机访问迭代器 | ->,[ ] | v = *p | *p = v | ++,--,+,-,+=,--= | ==,!=,<,>,<=,>= |
算法
- 算法是用于处理容器内容的一组函数。
- 要记住的要点:
- 算法提供了约60个算法函数,用于执行复杂的操作。
- 标准算法允许我们同时使用两种不同类型的容器。
- 算法不是容器的成员函数,而是独立的模板函数。
- 算法节省了大量的时间和精力。
STL算法可以分为以下几类:
- 非变动算法:非变动算法是指不改变容器对象中任何值,也不改变元素的顺序的算法。这些算法可用于所有容器对象,并使用前向迭代器。
- 变动算法:变动算法可用于改变容器的值。它们也可以用于改变元素的顺序。
- 排序算法:排序算法是用于对容器中的元素进行排序的修改算法。
- 集合算法:集合算法也称为排序范围算法。该算法用于对容器执行某些功能,极大提高程序的效率。
- 关系算法:关系算法用于处理数值数据。它们主要用于对容器中的所有元素执行数学运算。
函数对象
函数对象是封装在类中的函数,使其看起来像一个对象。函数对象通过使用面向对象的特性(如泛型编程)扩展了常规函数的特性。因此,我们可以说函数对象是一个智能指针,它比普通函数具有许多优点。
以下是函数对象相对于常规函数的优点:
- 函数对象可以具有成员函数和成员属性。
- 函数对象可以在使用之前进行初始化。
- 常规函数只有在签名不同时才能具有不同类型。而函数对象即使在签名相同时也可以具有不同的类型。
- 函数对象比常规函数更快。
函数对象也被称为'functor'(函数对象器)。函数对象是包含至少一个operator()函数定义的对象。这意味着如果我们声明一个类中定义了operator()函数的对象'd',我们可以将对象'd'用作普通函数。
假设'd'是一个类的对象,可以这样调用operator()函数:
d();
与下面的写法等价:
d.operator()();
让我们看一个简单的示例:
#include <iostream>
using namespace std;
class function_object
{
public: int operator()(int a, int b)
{
return a+b;
}
};
int main()
{
function_object f;
int result = f(5,5);
cout<<"a和b的相加结果是:"<<result;
return 0;
}
输出:
a和b的相加结果是:10
在上面的示例中,'f'是一个function_object类的对象,它包含operator()函数的定义。因此,'f'可以被用作普通函数来调用operator()函数。