ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] # 简介 STL 从广义上分为: 容器(container) 算法(algorithm) 迭代器(iterator),容器和算法之间通过迭代器进行无缝连接。STL 几乎所有的代码都采用了模板类或者模板函数,这相比传统的由函数和类组成的库来说提供了更好的代码重用机会 # 六大组件 STL提供了六大组件,彼此之间可以组合套用,这六大组件分别是:容器、算法、迭代器、仿函数、适配器、空间配置器。 * **容器**: 各种数据结构,如vector、list、deque、set、map等,用来存放数据,从实现角度来看,STL容器是一种class template。 * **算法**: 各种常用的算法,如sort、find、copy、`for_each`。从实现的角度来看,STL算法是一种function tempalte. * **迭代器**: 扮演了容器与算法之间的胶合剂,共有五种类型,从实现角度来看,迭代器是一种将`operator* , operator-> , operator++,operator--`等指针相关操作予以重载的class template. 所有STL容器都附带有自己专属的迭代器,只有容器的设计者才知道如何遍历自己的元素。原生指针(native pointer)也是一种迭代器。 * **仿函数**: 行为类似函数,可作为算法的某种策略。从实现角度来看,仿函数是一种重载了operator()的class 或者class template * **适配器**: 一种用来修饰容器或者仿函数或迭代器接口的东西。 * **空间配置器**: 负责空间的配置与管理。从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放的class tempalte. STL六大组件的交互关系,容器通过空间配置器取得数据存储空间,算法通过迭代器存储容器中的内容,仿函数可以协助算法完成不同的策略的变化,适配器可以修饰仿函数。 ## 迭代器 迭代器的种类: ![](https://img.kancloud.cn/f4/1c/f41ce2eb48fcc25074c572c748b37057_762x345.png) # 原理 ~~~ //数组容器 template<class T> class MyArray { public: //保护原生指针,给原生指针取别名 typedef T* iterator; MyArray() { mCapacity = 10; mSize = 10; p = new T[mCapacity]; for (int i = 0; i < mCapacity; i++) { p[i] = i + 1; } } //提供迭代器,开始位置的迭代器 T* begin() { return p; } //返回结束位置的迭代器 T* end() { return p + mSize; } public: T* p; int mCapacity; int mSize; }; //算法 template<class T> void printArray(T begin,T end) { for (; begin != end; ++begin) { cout << *begin << " "; } } void test01() { MyArray<int> arr; //获取容器提供的开始位置迭代器 MyArray<int>::iterator begin=arr.begin(); //获取容器提供的结束位置迭代器 MyArray<int>::iterator end = arr.end(); printArray(begin, end); } ~~~ # 简单的helloworld ~~~ #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector>//容器 #include<algorithm>//算法的头文件 #include<string> using namespace std; //加入算法的回调函数 void MyPrint(int val) { cout << val << " "; } //1.存储基础数据类型 void test01() { //容器 vector<int> v; v.push_back(10); v.push_back(20); v.push_back(30); v.push_back(40); v.push_back(50); //获取开始位置的迭代器 vector<int>::iterator begin = v.begin(); //获取结束位置的迭代器 vector<int>::iterator end = v.end(); /* void _For_each(_InIt _First, _InIt _Last, _Fn1& _Func) { for (; _First != _Last; ++_First) _Func(*_First); } */ //遍历算法 for_each(begin, end, MyPrint); cout << endl; } //2.容器存储对象 class Maker { public: Maker(string name, int age) { this->name = name; this->age = age; } public: string name; int age; }; ostream &operator<<(ostream &out, Maker &m) { out << "Name:" << m.name << " Age:" << m.age << endl; return out; } void test02() { vector<Maker> v; //往容器中存储对象 v.push_back(Maker("悟空", 18)); v.push_back(Maker("小林", 19)); v.push_back(Maker("贝吉塔", 25)); v.push_back(Maker("龟仙人", 200)); v.push_back(Maker("短笛", 180)); //获取开始和结束位置的迭代器 vector<Maker>::iterator begin = v.begin(); vector<Maker>::iterator end = v.end(); while (begin!=end) { cout << (*begin); begin++; } } //3.存储对象的指针 void test03() { vector<Maker*> v; //创建数据 Maker *m1 = new Maker("悟空", 18); Maker *m2 = new Maker("小林", 19); Maker *m3 = new Maker("贝吉塔",200 ); Maker *m4 = new Maker("龟仙人",180 ); Maker *m5 = new Maker("短笛", 18); v.push_back(m1); v.push_back(m2); v.push_back(m3); v.push_back(m4); v.push_back(m5); vector<Maker*>::iterator begin = v.begin(); vector<Maker*>::iterator end = v.end(); while (begin!=end) { cout << (*begin)->name << " " << (*begin)->age << endl; ++begin; } delete m1; delete m2; delete m3; delete m4; delete m5; } //4.容器嵌套容器 void test04() { vector<vector<int>> vs; vector<int> v1; vector<int> v2; vector<int> v3; vector<int> v4; vector<int> v5; for (int i = 0; i < 5; i++) { v1.push_back(i + 10); v2.push_back(i + 10); v3.push_back(i + 10); v4.push_back(i + 10); v5.push_back(i + 10); } vs.push_back(v1); vs.push_back(v2); vs.push_back(v3); vs.push_back(v4); vs.push_back(v5); vector<vector<int>>::iterator begin = vs.begin(); vector<vector<int>>::iterator end = vs.end(); while (begin!=end) { vector<int>::iterator sbegin = (*begin).begin(); vector<int>::iterator send = (*begin).end(); while (sbegin!=send) { cout << *sbegin << " "; ++sbegin; } cout << endl; ++begin; } } int main() { test04(); system("pause"); return EXIT_SUCCESS; } ~~~