文章目录

  • 1. 什么是STL?
  • 2. STL的优势
  • 3. STL版本?
  • 4. STL的六大组件
  • 5. 学习建议
  • 6. 为什么需要迭代器?
  • 7. 自己实现迭代器iterator
  • 8. STL中的5种迭代器
  • 9. STL中的iterator类
  • 10. 序列容器对比
  • 11. 容器适配器对比
  • 12. 关联容器对比

C++ STL标准库系列文章:

[STL] 1.简介
[STL] 2.序列容器 固定数组array(C++ 11)
[STL] 3.序列容器 动态数组vector
[STL] 4.序列容器 双端队列deque
[STL] 5.序列容器 双向链表list
[STL] 6.序列容器 单向链表forward_list(C++ 11)
[STL] 7.适配器简介
[STL] 8.容器适配器 栈stack
[STL] 9.容器适配器 队列queue
[STL] 10.容器适配器 优先队列priority_queue
[STL] 11.关联容器 集合set
[STL] 12.关联容器 映射map
[STL] 13.关联容器 多重集合multiset
[STL] 14.关联容器 多重映射multimap
[STL] 15.关联容器 无序集合unordered_set(C++ 11)
[STL] 16.关联容器 无序集合unordered_map(C++ 11)
[STL] 17.仿函数functor与函数对象
[STL] 18.预定义函数对象、仿函数适配器
[STL] 19.算法algorithm
[STL] 20.迭代器适配器
[STL] 21.空间配置器allocator

1. 什么是STL?

标准模板库 - 维基百科,自由的百科全书 (wikipedia.org)

标准模板库(英文:Standard Template Library,缩写:STL),是一个C++软件库,大量影响了C++标准程序库但并非是其的一部分。其中包含4个组件,分别为算法、容器、函数、迭代器。[1]

模板是C++程序设计语言中的一个重要特征,而标准模板库正是基于此特征。标准模板库使得C++编程语言在有了同Java一样强大的类库的同时,保有了更大的可扩展性。

2. STL的优势

  • 功能强大、代码精致

STL由惠普实验室的无数大牛们开发,设计精巧,功能强大,集成了优秀的算法。

  • 高可重用性

ST广泛使用模板泛型编程,代码具有高度的复用性。

  • 高性能、工业强度

ST提供的算法具有工业强度,高性能,用它可开发出性能高效的应用程序。

  • 开源跨平台

STL跨平台,而且开源,开发者可以很容易借鉴与扩展。

3. STL版本?

HP STL

HP STL是Alexandar Stepanov在惠普Palo Alto实验室工作时,与Meng Lee合作完成的。HP STL是C++ STL的第一个实现版本,而且是开放源码。其它版本的C++ STL一般是以HP STL为蓝本实现出来的。

SGI STL

由Silicon Graphics Computer Systems公司参照HP STL实现,主要设计者仍然是STL之父Alexandar Stepanov,被Linux的C++编译器GCC所采用。SGI STL是开源软件,源码可读性甚高。

STLport

为了使SGI STL的基本代码都适用于VC++和C++ Builder等多种编译器,俄国人Boris Fomitchev建立了一个free项目来开发STLport,此版本STL是开放源码的。

P.J.Plauger STL

由P.J.Plauger参照HP STL实现出来,被Visual C++编译器所采用,但不是开源的。

Rouge Wave STL

由Rouge Wave公司参照HP STL实现,用于Borland C++编译器中,这个版本的STL也不是开源的。

4. STL的六大组件

1、容器(Containers):各种数据结构,如Vector,List,Deque,Set,Map,用来存放数据,STL容器是一种Class Template,就体积而言,这一部分很像冰山载海面的比率。

2、算法(Algorithms):各种常用算法如Sort,Search,Copy,Erase,从实现的角度来看,STL算法是一种Function Templates。

3、迭代器(Iterators):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,共有五种类型,以及其它衍生变化,从实现的角度来看,迭代器是一种将:Operators*,Operator->,Operator++,Operator–等相关操作予以重载的Class Template。所有STL容器都附带有自己专属的迭代器——是的,只有容器设计者才知道如何遍历自己的元素,原生指针(Native pointer)也是一种迭代器。

4、仿函数(Functors): 行为类似函数,可作为算法的某种策略(Policy),从实现的角度来看,仿函数是一种重载了Operator()的Class 或 Class Template。一般函数指针可视为狭义的仿函数。

5、配接器(适配器)(Adapters):一种用来修饰容器(Containers)或仿函数(Functors)或迭代器(Iterators)接口的东西,例如:STL提供的Queue和Stack,虽然看似容器,其实只能算是一种容器配接器,因为 它们的底部完全借助Deque,所有操作有底层的Deque供应。改变Functor接口者,称为Function Adapter;改变Container接口者,称为Container Adapter;改变Iterator接口者,称为Iterator Adapter。配接器的实现技术很难一言蔽之,必须逐一分析。

6、分配器(Allocators):负责空间配置与管理,从实现的角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的Class Template。

​ ——《STL源码剖析》

5. 学习建议

路线:

  • C++数据结构
  • C++模板
  • STL标准库
  • Boost库

资源:

Containers - C++ Reference (cplusplus.com)

cppreference.com

6. 为什么需要迭代器?

#include "stdafx.h"
#include<iostream>
using namespace  std;/* 思考题一
现在有一个数组  int  arr[5] = { 1,2,3,4,5 };
void   Print(int  *begin, int  *end)
{
//此处编写代码
}
让 Print(arr, arr + 5);  实现打印所有元素?
*//*
void   Print(int  *begin, int  *end)
{//此处编写代码for (int *p = begin; p != end; ++p)//利用指针的++,依次访问每个元素{cout << *p << "        ";}cout << endl;
}
*//*  思考题二现在有一个链表,有5个Node节点:struct   Node
{
int  data;
Node*  next;
};void   Print(Node *begin, Node *end)
{
//此处编写代码
}让 Print(pHead,  pTail );  实现打印所有元素?
*/struct   Node
{int  data;Node*  next;
};ostream & operator <<(ostream&  o,const  Node &node)
{o << node.data << endl;return   o;
}/*
void   Print(Node *begin, Node *end)
{//此处编写代码for (Node *p    =begin;  p!= end ;  p=p->next) //指向下一个节点{cout << (*p).data << "     "; }cout << endl;
}
*///思考题三
//写出一个通用的Print 函数模板
template<class T>
void   Print(T  begin, T  end)
{//此处编写代码for (T  p = begin; p != end; ++p){cout << *p << "     ";}cout << endl;
}int main()
{//题目一测试int  arr[5] = { 1,2,3,4,5 };Print(arr, arr + 5); //arr + 5是指向 最后一个元素下一个的位置//Print<int *>(arr, arr + 5);//调用模板函数//题目二测试Node  n1;n1.data = 11;Node  n2;n2.data =22;Node  n3;n3.data = 33;Node  n4;n4.data = 44;Node  n5;n5.data = 55;n1.next = &n2;n2.next = &n3;n3.next = &n4;n4.next = &n5;n5.next = NULL;Print(&n1, n5.next);return 0;
}

7. 自己实现迭代器iterator

迭代器(iterator)是指针的抽象,它允许程序员以相同的方式处理不同的数据结构(容器)。

迭代器支持的一些基本操作:

  • =:迭代器赋值
  • ==:比较迭代器的相等性
  • !=:比较迭代器的不等性
  • ++:迭代器向后移动
  • --:迭代器向前移动
  • *:解引用,返回迭代器指向的元素
#include "stdafx.h"
#include<iostream>
using namespace  std;//思考题三
//写出一个通用的Print 函数模板
template<class T>
void   Print(T  begin, T  end)
{//此处编写代码for (T  p = begin; p != end; ++p){cout << *p << "     ";}cout << endl;
}//虽然数组不需要迭代器,因为指针就是一种特殊的迭代器
//也可以设计一个数组迭代器
class  ArrayIterator
{public:ArrayIterator(int *p) : _p(p) {}ArrayIterator  &  operator++(){ ++_p;//指针就是++指向下一个return  *this ;}bool   operator!=(const ArrayIterator & it){return  _p != it._p;}int&   operator*(){return   *_p;}//private: int * _p;
};//考虑设计一个中间类,让它支持operator ++,实际实现是链表的p=p->next
//链表迭代器
class  ListIterator
{public:ListIterator(Node *p) : _p(p) {} ListIterator  &  operator++(){//链表的真正操作_p = _p->next;return  *this;}bool   operator!=(const ListIterator & it){return  _p != it._p;}Node&   operator*( ){return   *_p;}
//private: Node * _p;
};int main()
{//使用链表迭代器ListIterator begin(&n1);ListIterator end(n5.next);Print(begin, end);return 0;
}

8. STL中的5种迭代器

  • 输入迭代器(Input iterator)
  • 输出迭代器(Output Iterator)
  • 前向迭代器(Forward iterator)
  • 双向迭代器(Bidirectional iterator)
  • 随机访问迭代器(Random Access iterator)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-on3WXlhN-1620021492142)(C:\Users\tangx\AppData\Roaming\Typora\typora-user-images\image-20210503133856493.png)]

不同的数据结构(容器)支持的迭代器类型不同,比如数组结构可支持随机访问迭代器,但是链表结构就无法支持,链表往往设计为双向迭代器。

9. STL中的iterator类

iterator类是一个基类模板,可用于从它派生迭代器类。它不提供迭代器具有的任何功能,仅提供了些默认成员类型,这些并不是迭代器类型必须需具备的,它们可能是有用的。

定义:

iterator - C++ Reference (cplusplus.com)

template <class Category, class T, class Distance = ptrdiff_t,class Pointer = T*, class Reference = T&>struct iterator {typedef T         value_type;typedef Distance  difference_type;typedef Pointer   pointer;typedef Reference reference;typedef Category  iterator_category;};

Category

迭代器所属的类别。 它必须是以下迭代器标签之一:

迭代器标签 迭代器的类别 迭代器类型
input_iterator_tag Input Iterator 输入迭代器
output_iterator_tag Output Iterator 输出迭代器
forward_iterator_tag Forward Iterator 前向迭代器
bidirectional_iterator_tag Bidirectional Iterator 双向迭代器
random_access_iterator_tag Random-access Iterator 随机访问迭代器

T

迭代器指向的元素类型。

Distance

键入以表示两个迭代器之间的差异。

Pointer

类型,表示指向迭代器指向的元素的指针。

Reference

类型,表示对迭代器指向的元素的引用。

示例代码:

#include "stdafx.h"
#include<iostream>
#include<iterator>using namespace  std;class  A
{public:typedef  int  MYINT;  //内部类型using   MYFLOAT = float; //内部类型
};class MyIterator : public std::iterator<std::random_access_iterator_tag, int>
{int* p;
public:MyIterator(int* x) :p(x) {}MyIterator(const MyIterator& mit) : p(mit.p) {}MyIterator& operator++() { ++p; return *this; }MyIterator operator++(int) { MyIterator tmp(*this); operator++(); return tmp; }bool operator==(const MyIterator& rhs) const { return p == rhs.p; }bool operator!=(const MyIterator& rhs) const { return p != rhs.p; }int& operator*() { return *p; }//int &operator[](int index) {    return   *(p + index); }
};int main()
{//A::MYINT  a = 100;//A::MYFLOAT b = 100;//定义一个迭代器对象iterator<  input_iterator_tag   , int>  it ;//内部类型:iterator_category代表迭代器类别类型cout << typeid(iterator<input_iterator_tag, int>::iterator_category).name() << endl;//迭代器指向元素的类型cout << typeid( iterator<input_iterator_tag, int>::value_type).name() << endl;//迭代器指向元素的指针类型cout << typeid(iterator<input_iterator_tag, int>::pointer).name() << endl;//迭代器指向元素的引用类型 cout << typeid(iterator<input_iterator_tag, int>::reference).name() << endl;//迭代器指向元素的指针类型 相减得到的差值类型cout << typeid(iterator<input_iterator_tag, int>::difference_type).name() << endl;iterator<input_iterator_tag, int>::value_type  a = 100;iterator<input_iterator_tag, int>::pointer  pA = &a;iterator<input_iterator_tag, int>::reference  b=a;cout << a << "     " << *pA << endl;b = 200;cout << a<<"        "<< b << endl;iterator<input_iterator_tag, int>::pointer  pB = &a+2;iterator<input_iterator_tag, int>::difference_type  c = pB - pA;cout << c << endl;//测试自定义的迭代器int numbers[] = { 10,20,30,40,50 };MyIterator from(numbers);MyIterator until(numbers + 5);for (MyIterator it = from; it != until; it++)std::cout << *it << ' ';std::cout << '\n';//cout << from[3] << endl;MyIterator::value_type  x = 100;return 0;
}

10. 序列容器对比

序列容器 数据结构 底层实现 迭代器 优缺点
array (c++11) 固定数组 普通数组、连续内存 随机访问迭代器 快速随机访问、在中间插入、删除元素效率较低、无法扩容
vector 动态数组 new 堆内存、连续内存 随机访问迭代器 快速随机访问、在中间插入、删除元素效率较低、容量可动态增长
deque 双端队列 一个中央控制器和多个缓冲区、不连续 随机访问迭代器 快速随机访问、两端插入、删除效率高
list 双向链表 双向链表、不连续 双向迭代器 不支持随机访问、可双向遍历、任意位置插入、删除元素效率高
forward_list (c++11) 单向链表 单向链表、不连续 前向迭代器 不支持随机访问、单向遍历、任意位置插入、删除元素效率高

11. 容器适配器对比

容器适配器 数据结构 底层实现 迭代器 特点
stack 底层默认用queue实现,也可以是vectorlist 不支持 先进后出 FILO
queue 队列 底层默认用queue实现,也可以是list 不支持 先进先出 FIFO
priority_queue 优先队列 底层默认用vector为容器,使用堆heap为处理规则来排序。容器也可以是deque 不支持 优先级最高(或最低)的元素先出

12. 关联容器对比

序列容器 数据结构 底层实现 迭代器 优缺点
set 集合 红黑树 双向迭代器 key唯一、有序
map 映射 红黑树 双向迭代器 key唯一、有序、value可重复
multiset 多重集合 红黑树 双向迭代器 key可重复、有序
multimap 多重映射 红黑树 双向迭代器 key可重复、有序、value可重复
unordered_set 无序集合 哈希表 双向迭代器 key唯一、无序
unordered_map 无序映射 哈希表 双向迭代器 key唯一、无序、value可重复
unordered_multiset (c++11) 无序多重集合 哈希表 双向迭代器 key可重复、无序
unordered_multimap (c++11) 无序多重映射 哈希表 双向迭代器 key可重复、无序、value可重复

C++ STL标准模板库简介相关推荐

  1. 【C++】STL(标准模板库)简介

    STL简介 文章目录 STL简介 什么是STL STL版本 STL的六大组件 如何学习STL STL的缺陷 什么是STL STL(standard template libaray-标准模板库):是C ...

  2. 19.3 C++STL标准模板库大局观-容器的说明和简单应用例续

    19.1 C++STL标准模板库大局观-STL总述.发展史.组成与数据结构谈 19.2 C++STL标准模板库大局观-容器分类与array.vector容器精解 19.3 C++STL标准模板库大局观 ...

  3. 19.1 C++STL标准模板库大局观-STL总述、发展史、组成与数据结构谈

    19.1 C++STL标准模板库大局观-STL总述.发展史.组成与数据结构谈 19.2 C++STL标准模板库大局观-容器分类与array.vector容器精解 19.3 C++STL标准模板库大局观 ...

  4. 【跟学C++】C++STL标准模板库——算法详细整理(下)(Study18)

    文章目录 1.简介 2.STL算法分类及常用函数 2.2.变序算法(二) 2.2.1 替换算法(2个) 2.2.2 排序算法(6个) 2.2.3 分区算法(4个) 2.2.4 可用于排序容器的算法(3 ...

  5. C++提高编程----STL标准模板库-常用容器

    STL标准模板库(Standard Template Library)-常用容器 C++的,面向对象和泛型编程,目的就是提高代码的复用性:为了建立数据结构和算法的统一标准,诞生了STL 一.STL初识 ...

  6. STL(标准模板库)理论基础与容器

    10.1 STL(标准模板库)理论基础 10.1.1基本概念 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被 ...

  7. 【跟学C++】C++STL标准模板库——算法详细整理(中)(Study18)

    文章目录 1.简介 2.STL算法分类及常用函数 2.1.变序算法(一) 2.2.1 初始化算法(2个) 2.2.2 修改算法(2个) 2.2.3 复制算法(6个) 2.2.4 删除算法(6个) 3. ...

  8. 补8-5日复习内容 STL 标准模板库的容器

    //有关 STL 标准模板库的函数 /* string 的 */ /* #include <iostream> #include <string> #include <w ...

  9. stl标准模板库_C ++标准模板库(STL)中的array :: fill()

    stl标准模板库 fill() is a member function of "array container", which sets a given value to all ...

最新文章

  1. 解决报错:Can't read private key和./build-aux/cksum-schema-check: Permission denied
  2. python待遇如何-老男孩学Python后就业如何?Python待遇高吗?
  3. 【一周入门MySQL—2】单表查询
  4. Intel处理器CPUID指令学习
  5. HCIE-Security Day11:双机热备,从VRRP到VGMP
  6. python-常用模块-time、datetime模块
  7. 思科模拟器之工大瑞普版(u7)下载地址
  8. pta C语言选择题
  9. 提升生产力,7 款好用的原型图工具推荐给你
  10. 华三路由交换配置命令_h3c路由器配置命令
  11. Android 和风天气+腾讯地图
  12. 深圳高中女生街头版someone like you
  13. 利用python画分形图_「分形」python简单的分形图片 - seo实验室
  14. linux中日志服务器的搭建
  15. 中科院计算机控制学院难度,16年自动化所复试失败经验
  16. win7 svchost.exe 占用内存cpu过高
  17. MAC电脑配置maven
  18. DirectX11 With Windows SDK--11 混合状态
  19. DAE向春秋航空公司交付三架新型A320飞机中的第一架
  20. html 字前边自动加点,css实现文字越界加点点点显示,并且后面紧跟一个图标

热门文章

  1. 猿来小课web前端介绍html语言基础学习
  2. LoRa模块(内置MCU),亿百特E22-400T30S,广播监听、定点传输、中继组网
  3. 苹果wifi网速慢怎么办_WiFi用着用着就断了?这样设置WiFi永不断网,大部分人不知道...
  4. 微信公众号引流源码?基本上没啥用!
  5. smart200+步进控制
  6. repo (一) 简介
  7. 为什么选择0.1uF电容而不是0.01uF电容?
  8. 【c++】VSCode配置 c++ 环境(小白教程)
  9. python找完数 pta_PTA——完全数
  10. php创建网址打不开,php网站无法打开怎么办