STL库 总览

  泛型程序编程是C++支持的另一种编程模式。与OPP的目标相同:使重用代码和抽象通用概念的技术更简单。OPP强调的是编程的数据方面,泛型编程强调的是独立于特定数据类型。OPP是一个管理大型项目的工具,泛型编程提供了执行常见任务(如对数据排序、合并链表)的工具。


  

1 泛型程序设计

  泛型程序设计就是时候,将程序设计的尽量的通用。STL标准库就是泛型程序设计的一个很好的范例。
  ◇ 编写不依赖具体数据类型的程序;
  ◇ 将算法从特定的数据结构中抽象出来,成为通用的;
  ◇ C++类模板为泛型编程奠定了关键基础。

两个术语:
概念
模型
在STL库中,很多模板的实现,就是用概念来命名模板参数的,用概念做模板参数名:
  ◇ 为概念赋予一个名称,并使用该名称作为模板参数名。
eg:
template< class Sortable >
void insertionSort(Sortable a[],int n);

2 STL标准模板库

  ◇ 标准模板库STL(standard template library)定义了一套概念体系,为泛型程序设计提供了逻辑基础。
  ◇ STL中的各个类模板、函数模板的参数都是用这个体系中的概念来规定的。
  ◇ 使用STL的模板时,类型参数既可以是C++标准库中已有的类型,也可是自定义的类型----只要这些类型是所要求概念的模板。

2.1 STL库的基本组件

  ◇ 容器(container)
  ◇ 迭代器(iterator)
  ◇函数对象(function object)
  ◇ 算法(algorithms)
  
关系:
在这里插入图片描述
◇ 迭代器是算法和容器的桥梁:
  ·将迭代器作为算法的参数,通过迭代器来访问容器而不是把容器直接作为算法的参数;
◇ 将函数对象作为算法的参数而不是将函数作为执行的运算作为算法的一部分。
◇ 使用STL中提供的或自定义的迭代器和函数对象,配合STL的算法,可以组合出各种功能。

2.1.1 STL基本组件----容器

◇ 容纳,包含一组元素的对象;
◇ 基本容器类模板
  ·顺序容器:
  array(数组)、vector(向量)、deque(双端队列)、forward_list(单链表)、list(链表)
  ·(有序)关联容器:
  set(集合)、multiset(多重集合)、map(映射)、multimap(多重映射)
  ·(无序)关联容器:
  unordered_set(无序集合)、unordered_multiset(无序多重集合)、
  unordered_map(无序映射)、unordered_multimap(无序多重映射)

仅仅有这些容器类模板还不够,还需要栈、队列,其实 栈 和 队列 就是存取操作受限制的线性表,在STL库中也是这样处理的:在基本容器的基础上可以附加上适配器
  ◇ stack(栈)
  ◇ queue(队列)
  ◇ priority_queue(优先队列)

2.1.2 STL基本组件----迭代器

◇ 提供了顺序访问容器中每个元素的方法;
◇ 可以使用 ++ 运算符来获得指向下一个元素的迭代器;
◇ 可以使用 * 运算符访问迭代器所指向的元素,如果元素类型是类或者结构体,还可以使用 -> 访问其成员;
◇ 迭代器是泛化的指针:指针本身就是一种迭代器;
◇ 使用独立于STL容器的迭代器,需要包含头文件< iterator > 。

2.1.3 STL基本组件----函数对象

◇ 一个行为类似函数的对象,对它可以像调用函数一样调用。
◇ 函数对象是泛化的函数:任何普通的函数和任何重载了 () 运算符的类的对象都可以作为函数对象使用
◇ 使用STL的函数对象,需要包含头文件< functional >

2.1.4 STL基本组件----算法

◇ 可以广泛的用于不同的对象和内置的数据类型。
◇ STL中有70多种算法:排序、消除、计数、比较、变换、置换、容器管理,等等
◇ 需要包含< algorithm >

3 迭代器

  迭代器是算法和容器之间的桥梁,因为有这个桥梁,算法和容器就可以独立,彼此就更通用。
  ◇ 迭代器是算法和容器的桥梁:
   · 迭代器用作访问容器中的元素;
   · 算法不直接操作容器中的数据,而是通过迭代器间接操作
  ◇ 迭代器是算法和容器的桥梁:
   · 增加新的算法,无需影响容器的实现
   · 增加新的容器,原有的算法也能实现

输入流迭代器和输出流迭代器
◇ 输入流迭代器
 istream_iterator
  ·以输入流(如cin)为参数构造
  ·可用*(p++)获得下一个输入元素

◇ 输出流迭代器
 ostream_iterator
  ·构造时需提供输出流(如cout)
  ·可用 *(p++)=x 将x输出到输出流

◇二者都属于适配器
  ·适配器是用来为已有对象提供新的接口的对象
  ·输入流适配器和输出流适配器为流对象提供了迭代器 的接口

迭代器分类:
迭代器分类
迭代器支持的操作:
 ◇ 迭代器是泛化的指针,提供了类似指针的操作(诸如 ++ * -> 运算符)
 ◇ 输入迭代器
  · 可以用来从序列中读取数据,如输入流迭代器
 ◇ 输出流迭代器
  · 允许向序列中写入数据,如输出流迭代器
 ◇ 前向迭代器
  · 既是输入流迭代器又是输出流迭代器,并且可以对序列进行单向的遍历
 ◇ 双向迭代器
  · 与前向迭代器相似,但是在两个方向上都可以对数据遍历
 ◇ 随机访问迭代器
  · 也是双向迭代器,但是能在序列中的任意两个位置之间进行跳转,如指针、使用vector的begin()、end()函数得到的迭代器。

用两个迭代器表示一个区间:
 ◇ 两个迭代器表示一个区间:[p1,p2)
 ◇STL算法以迭代器的区间作为输入,传递输入数据
 ◇合法区间
  · p1经过n次(n>0)自增(++)操作后满足p1==p2
 ◇ 区间包含p1,但不包含p2

4 容器的基本功能与分类

  ◇ 容器类是容纳、包含一组元素或元素集合的对象的对象
  ◇ 基于容器中元素的组织方式分类:顺序容器、关联容器
  ◇ 按照与容器所关联的迭代器类型分类:可逆容器、随机访问容器

◇ 顺序容器:
 ·array(数组)、vector(向量)、deque(双端队列)、forward_list(单链表)、list(链表)
◇ (有序)关联容器:
 ·set(集合)、multiset(多重集合)、map(映射)、multimap(多重映射)
◇ (无序)关联容器:
 ·unordered_set(无序集合)、unordered_multiset(无序多重集合)、
 ·unordered_map(无序映射)、unordered_multimap(无序多重映射)

◇容器的通用功能
 · 用默认构造函数构造空容器
 · 支持关系运算符:== != < <= > >=
 · begin() end() : 获得容器首位迭代器
 · clear() : 将容器清零
 · empty() : 判断容器是否为空
 · size() : 得到容器元素个数
 · s1.swap(s2) : 将s1和s2两容器内容交换
◇相关数据类型(S表示容器类型)
 · S::iterator : 指向容器元素的迭代器类型
 · S::const_iterator : 常迭代器类型

对可逆容器的访问
 ◇ STL为每个可逆容器都提供了逆向迭代器,逆向迭代器可以通过下面的成员函数得到:
 · rbegin() : 指向容器尾逆向迭代器
 · rand() : 指向容器首的逆向迭代器
 ◇ 逆向迭代器的类型名的表示方式如下:
 · S::reverse_iterator : 逆向迭代器类型
 · S::const_reverse_iterator : 逆向常迭代器类型

随机访问容器
 ◇ 支持对容器的元素进行随机访问
s[n] : 获得容器s的第n个元素

4.1 顺序容器

 ◇ STL中的顺序容器
 · 向量(vector)
 · 双端队列(deque)
 · 列表(list)
 · 单向列表(forward_list)
 · 数组(array)
以上顺序容器在逻辑上可以看做一个长度可扩展的数组

 ◇ 元素线性排列,可以随时在指定位置插入元素和删除元素

 ◇ 必须符合Assignable这一概念(即具有公有的复制构造函数并可以使用 = 赋值)。

 ◇ array对象的大小固定,forward_list有特殊的添加和删除操作。

顺序容器的接口(不包含单向列表(forward_list)和数组(array))
 ◇ 构造函数
 ◇ 赋值函数
  · insert,push_front(只对list和deque),push_back,emplace,emplace_front
 ◇ 删除函数
  · erase,clear,pop_front(只对list和deque),pop_back,emplace_back
 ◇ 首位元素的直接访问
  · front,back
 ◇ 改变大小
  · resize

4.2 顺序容器的插入迭代器与适配器

  ◇ 用于向容器的头部,尾部或者中间指定位置插入元素的迭代器
  ◇ 包括前插迭代器(front_inserter)、后插迭代器(back_inserter)和任意位置插入迭代器(insterer)

eg:
lists;
back_inserter iter(s);
*(iter++)=5; //通过iter把5插入s末尾

顺序容器的适配器
  ◇ 以顺序容器尾基础构建一些常用的数据结构,是对顺序容器的封装
   · 栈(stack):最先压入的元素最后被弹出
   · 队列(queue):最先压入的元素最先被弹出
   · 优先级队列(priority_queue):最“大”元素最先被弹出

栈模板和队列模板
  ◇ 栈模板
   template< class T ,class Sequence = deque > class stack;
  ◇ 队列模板
   template< class T ,class FrontInsertionSequence= deque > class queue;
  ◇ 栈可以用任何一种顺序容器作为基础容器,而队列只允许前插顺序容器(双端队列或列表)

栈和队列共同支持的操作
  ◇ s1 op s2 op可以是== != < <= > >=
  ◇ s.size() 返回s元素个数
  ◇ s.empty() 返回s是否为空
  ◇ s.push(t) 将元素t压入
  ◇ s.pop 讲一个元素弹出
  ◇ 都不支持迭代器,因为不允许任意元素的访问

栈的操作:s.top() 返回栈顶元素的引用
队列操作:s.front() s.back() 获得对首/尾的引用

  ◇参考:《C++语言程序设计 郑莉》

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值