C++STL复习
参考文献
STL组成
STL组成 | 含义 |
---|---|
容器 | 一些封装数据结构的模板类,例如 vector 向量容器、list 列表容器等。 |
算法 | STL 提供了非常多(大约 100 个)的数据结构算法,它们都被设计成一个个的模板函数,这些算法在 std 命名空间中定义,其中大部分算法都包含在头文件 |
迭代器 | 在 C++ STL 中,对容器中数据的读和写,是通过迭代器完成的,扮演着容器和算法之间的胶合剂。 |
函数对象 | 如果一个类将 () 运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象(又称仿函数)。 |
适配器 | 可以使一个类的接口(模板的参数)适配成用户指定的形式,从而让原本不能在一起工作的两个类工作在一起。值得一提的是,容器、迭代器和函数都有适配器。 |
内存分配器 | 为容器类模板提供自定义的内存申请和释放功能,由于往往只有高级用户才有改变内存分配策略的需求,因此内存分配器对于一般用户来说,并不常用。 |
迭代器
定义
迭代器定义方式 | 具体格式 |
---|---|
正向迭代器 | 容器类名::iterator 迭代器名; |
常量正向迭代器 | 容器类名::const_iterator 迭代器名; |
反向迭代器 | 容器类名::reverse_iterator 迭代器名; |
常量反向迭代器 | 容器类名::const_reverse_iterator 迭代器名;容器 |
序列式容器
包括 array、vector、deque、list 和 forward_list 容器。
vector
|
-
创建
std::vector<double> values;
std::vector<double> values(20); //指定元素个数
std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
std::vector<double> values(20, 1.0);//初始值默认为1.0
int num=20;
double value =1.0;
std::vector<double> values(num, value); //也可以是变量
std::vector<char>value1(5, 'c');
std::vector<char>value2(value1);//用已有的容器创建
int array[]={1,2,3};
std::vector<int>values(array, array+2);//values 将保存{1,2}
std::vector<int>value1{1,2,3,4,5};
std::vector<int>value2(std::begin(value1),std::begin(value1)+3);//value2保存{1,2,3}std可省去
-
增加容量
values.reserve(20);
-
迭代器用法
//遍历 vector 容器。
//需要引入 vector 头文件
using namespace std;
int main()
{
vector<int> v{1,2,3,4,5,6,7,8,9,10}; //v被初始化成有10个元素
cout << "第一种遍历方法:" << endl;
//size返回元素个数
for (int i = 0; i < v.size(); ++i)
cout << v[i] <<" "; //像普通数组一样使用vector容器
//创建一个正向迭代器,当然,vector也支持其他 3 种定义迭代器的方式
cout << endl << "第二种遍历方法:" << endl;
vector<int>::iterator i;
//用 != 比较两个迭代器
for (i = v.begin(); i != v.end(); ++i)
cout << *i << " ";
cout << endl << "第三种遍历方法:" << endl;
for (i = v.begin(); i < v.end(); ++i) //用 < 比较两个迭代器
cout << *i << " ";
cout << endl << "第四种遍历方法:" << endl;
i = v.begin();
while (i < v.end()) { //间隔一个输出
cout << *i << " ";
i += 2; // 随机访问迭代器支持 "+= 整数" 的操作
}
} -
成员函数
函数成员 函数功能 begin() 返回指向容器中第一个元素的迭代器。 end() 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。 rbegin() 返回指向最后一个元素的迭代器。 rend() 返回指向第一个元素所在位置前一个位置的迭代器。 cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。 size() 返回实际元素个数。 max_size() 返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。 resize() 改变实际元素的个数。 capacity() 返回当前容量。 empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。 reserve() 增加容器的容量。 shrink _to_fit() 将内存减少到等于当前元素实际所使用的大小。 operator[ ] 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。 at() 使用经过边界检查的索引访问元素。 front() 返回第一个元素的引用。 back() 返回最后一个元素的引用。 data() 返回指向容器中第一个元素的指针。 assign() 用新元素替换原有内容。 push_back() 在序列的尾部添加一个元素。 pop_back() 移出序列尾部的元素。 insert() 在指定的位置插入一个或多个元素。 erase() 移出一个元素或一段元素。 clear() 移出所有的元素,容器大小变为 0。 swap() 交换两个容器的所有元素。 emplace() 在指定的位置直接生成一个元素。 emplace_back() 在序列尾部生成一个元素。 C++ 11 标准库还新增加了 begin() 和 end() 这 2 个函数,和 vector 容器包含的 begin() 和 end() 成员函数不同,标准库提供的这 2 个函数的操作对象,既可以是容器,还可以是普通数组。当操作对象是容器时,它和容器包含的 begin() 和 end() 成员函数的功能完全相同;如果操作对象是普通数组,则 begin() 函数返回的是指向数组第一个元素的指针,同样 end() 返回指向数组中最后一个元素之后一个位置的指针(注意不是最后一个元素)。
array(c++11)
关联式容器
-
关联式容器则大不一样,此类容器在存储元素值的同时,还会为各元素额外再配备一个值(又称为“键”,其本质也是一个 C++ 基础数据类型或自定义类型的元素),它的功能是在使用关联式容器的过程中,如果已知目标元素的键的值,则直接通过该键就可以找到目标元素,而无需再通过遍历整个容器的方式。
-
底层选用了 「红黑树」这种数据结构来组织和存储各个键值对。
-
C++ STL 标准库提供了 4 种关联式容器,分别为 map、set、multimap、multiset
关联式容器名称 | 特点 |
---|---|
map | 定义在 |
set | 定义在 |
multimap | 定义在 |
multiset | 定义在 |
map
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Q's blog!
评论