- (一)STL概念
- (1)STL的六大组件详细功能如下:
- (2)迭代器(指针类型)的种类:
- (二)结合使用vector和迭代器
- (1)第一种:打印vector中的元素
- (2)第二种:
- (3)第三种:使用标准算法头文件中的for_each函数
- (4)使用vector存放自定义类型并用迭代器输出每个元素
- (5)假设在(4)的基础上,我们将所有的vector中的User类型换成User*,该如何打印呢
STL是standard template library的首字母缩写,是标准模板库
思想:泛型编程(基于函数模板,类模板实现)、提高复用性
STL分为:容器、算法、迭代器;容器和算法之间通过迭代器无缝连接
STL的六大组件:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
(1)STL的六大组件详细功能如下:| 名称 | 功能 |
|---|---|
| 容器 | vector、list、deque、set、map等存放数据的结构 |
| 算法 | sort、find、copy、for_each等常用算法 |
| 迭代器 | 使用算法控制容器中的数据 |
| 仿函数 | 类似函数,算法的某种策略 |
| 适配器 | 修饰容器、仿函数、迭代器的一种接口 |
| 空间配置器 | 负责空间的配置和管理 |
注:
- 算法需要使用迭代器才能对容器起作用
- 普通的变量访问不了容器;
- 每种容器都有自己专属的迭代器;
| 种类 | 功能 | 支持运算 |
|---|---|---|
| 输入迭代器 | 只读访问 | ++、 ==、 != |
| 输出迭代器 | 只写访问 | ++ |
| 前向迭代器 | 读写,向前推进迭代器 | ++、==、!= |
| 双向迭代器 | 读写,向前向后操作 | ++、– |
| 随机访问迭代器 | 读写,可访问任意数据 | ++、–、[n]、-n、<、>、<=、>= |
#include(2)第二种:#include using namespace std; void ShowTest1() { vector vc; vc.push_back(1); vc.push_back(2); vc.push_back(3); vc.push_back(4); //定义两个迭代器分别指向第一个元素、最后一个元素+1的位置 vector ::iterator itBegin = vc.begin(); vector ::iterator itEnd = vc.end(); while (itBegin != itEnd) { cout << *itBegin++ << endl; } }
void ShowTest2()
{
vector vc;
vc.push_back(1);
vc.push_back(2);
vc.push_back(3);
vc.push_back(4);
for(vector::iterator it = vc.begin(); it != vc.end(); it++)
{
cout << *it<< endl;
}
}
(3)第三种:使用标准算法头文件中的for_each函数
#include#include #include //标准算法头文件 void ShowTest(int val) { cout << val << endl; } int main() { vector vc; vc.push_back(1); vc.push_back(2); vc.push_back(3); vc.push_back(4); for_each(vc.begin(), vc.end(), ShowTest); return 0; }
对于第三种我们看看for_each的部分源码是如何实现的:
//模板类型_Init 和_Fn template_Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) { // perform function for each element [_First, _Last) //为每个元素执行函数 //检验范围 _Adl_verify_range(_First, _Last); //首元素 auto _UFirst = _Get_unwrapped(_First); //尾元素后一位地址 const auto _ULast = _Get_unwrapped(_Last); for (; _UFirst != _ULast; ++_UFirst) { _Func(*_UFirst); } return _Func; }
通过源码看出,其实for_each的实现和第一种的方式大同小异。
(4)使用vector存放自定义类型并用迭代器输出每个元素#include#include #include using namespace std; class User { public: User(string name, int age) { _name = name; _age = age; } string _name; int _age; }; void Test() { vector vc; User u1("HuTao", 16); User u2("XiangLing", 18); User u3("ChongYun", 19); User u4("XingQiu", 18); vc.push_back(u1); vc.push_back(u2); vc.push_back(u3); vc.push_back(u4); for (vector ::iterator it = vc.begin(); it != vc.end(); it++) { cout <<"name:" < _name << " "<<"age :"<< it->_age < 结果:
(5)假设在(4)的基础上,我们将所有的vector中的User类型换成User*,该如何打印呢
分析:
- 上面有提过其实迭代器就是一个泛型的指针,可以是任意合法类型,指向vector(容器)中的任意一个元素的地址,逻辑图如下:
- 那么将所有的vector换成vector
也就很好理解了, 此时的迭代器就是一个二级指针
逻辑图如下:
- 所以vector换成User*类型,就得使用两次解引用(*(*it))._name 或者(*it)->_name来访问容器中的元素了
void Test() { User u1("HuTao", 16); User u2("XiangLing", 18); User u3("ChongYun", 19); User u4("XingQiu", 18); vectorvc; vc.push_back(&u1); vc.push_back(&u2); vc.push_back(&u3); vc.push_back(&u4); for (vector ::iterator it = vc.begin(); it != vc.end(); it++) { cout << "name:" << (*(*it))._name << " " << "age :" << (*it)->_age << endl; } } 结果:



