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 | 它遵循后进先出(LIFO)原则。 | <stack> |
无迭代器 |
queue | 它遵循先进先出(FIFO)原则。 | <queue> |
无迭代器 |
Priority-queue | 首个输出元素总是具有最高优先级的元素。 | <queue> |
无迭代器 |
容器的分类:
- 序列容器
- 关联容器
- 派生容器
注意:每个容器类都包含一组可以用来操作内容的函数。
迭代器
- 迭代器是类似指针的实体,用于访问容器中的个别元素。
- 迭代器按顺序从一个元素移动到另一个元素。这个过程被称为遍历容器。
- 迭代器主要包含两个函数:
begin() :成员函数begin()返回指向向量的第一个元素的迭代器。
end() :成员函数end()返回指向容器的尾后元素的迭代器。
迭代器分类
迭代器主要分为五个类别:
- 输入迭代器:
- 输入迭代器是一种允许程序从容器中读取值的迭代器。
- 解引用输入迭代器允许我们从容器中读取一个值,但不会改变该值。
- 输入迭代器是单向迭代器。
- 输入迭代器可以递增但不能递减。
- 输出迭代器:
- 输出迭代器与输入迭代器类似,但它允许程序修改容器的值,但不允许读取它。
- 它是单向迭代器。
- 它是只写迭代器。
- 前向迭代器:
- 前向迭代器使用++操作符在容器中导航。
- 前向迭代器逐个遍历容器的每个元素。
- 双向迭代器:
- 双向迭代器与前向迭代器类似,但它还可以向后移动。
- 它是双向迭代器。
- 它可以递增和递减。
- 随机访问迭代器:
- 随机访问迭代器可用于访问容器的随机元素。
- 随机访问迭代器具有双向迭代器的所有功能,还有一个额外的功能,即指针加法。通过使用指针加法操作,我们可以访问容器的随机元素。
迭代器支持的操作
iterator | Element access | Read | Write | Increment operation | Comparison |
---|---|---|---|---|---|
input | -> |
v = *p |
++ |
==,!= |
|
output | *p = v |
++ |
|||
forward | -> |
v = *p |
*p = v |
++ |
==,!= |
Bidirectional | -> |
v = *p |
*p = v |
++,-- |
==,!= |
Random access | ->,[ ] |
v = *p |
*p = v |
++,--,+,-,+=,--= |
==,!=,<,>,<=,>= |
算法
算法是用于处理各种容器内容的函数。
要记住的要点:
- 算法提供大约60个算法函数来执行复杂操作。
- 标准算法允许我们同时处理两种不同类型的容器。
- 算法不是容器的成员函数,而是独立的模板函数。
- 算法节省了大量的时间和精力。
- 如果我们想要使用STL算法,必须在程序中包含
头文件。 STL算法可以分为以下几类:
- 非变动算法 :非变动算法是指不改变容器对象的任何值,也不改变它们出现的顺序的算法。这些算法可以用于所有的容器对象,并且它们使用前向迭代器。
- 变动算法 :变动算法可以用于改变容器的值。它们也可以用于改变元素出现的顺序。
- 排序算法 :排序算法是修改算法,用于对容器中的元素进行排序。
- 集合算法 :集合算法也被称为有序范围算法。这个算法用于对一个容器执行一些操作,极大地提高了程序的效率。
- 关系算法 :关系算法用于处理数值数据。它们主要用于对容器中的所有元素执行数学运算。
函数对象
函数对象是一个封装在类中的函数,使它看起来像一个对象。函数对象通过使用面向对象的特性,如泛型编程,扩展了常规函数的特性。因此,我们可以说函数对象是一个比普通函数更加有优势的智能指针。
函数对象相比于常规函数的优势如下:
- 函数对象可以有成员函数和成员属性。
- 函数对象可以在使用之前初始化。
- 常规函数只有在签名不同时才能具有不同的类型。函数对象即使在签名相同时也可以具有不同的类型。
- 函数对象比常规函数更快。
函数对象也被称为’ 函数子 ‘。函数对象是一个至少包含一个定义了 operator() 函数的对象。这意味着如果我们在一个类中声明了一个对象’d’,其中定义了 operator() 函数,我们可以将对象’d’用作一个常规函数。
假设’d’是一个类的对象,operator()函数可以被调用为:
d();
which is same as:
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<<"Addition of a and b is : "<<result;
return 0;
}
输出:
Addition of a and b is : 10
在上面的示例中,’f’是一个函数对象类的对象,它包含了operator()函数的定义。因此,’f’可以像普通函数一样被调用operator()函数。