STL(标准模板库)泛型编程的基础介绍

一、概述

  1. 软件界一直希望建立一种可重复利用的东西;
  2. c++的面向对象和泛型编程思想,目的是复用性的提升
  3. 大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作
  4. 建立数据结构和算法的一套标准,所以诞生了STL

二、STL基本概念

  1. STL(标准模板库),是一种泛型编程。面向对象编程关注的是编程的数据方面,而泛型编程关注的是算法,它们之间的共同点是抽象和创建可重用代码,但理念决然不同。
  2. 泛型编程旨在编写独立于数据类型的代码。在c++中,完成通用程序的工具是模板。模板使得能够按泛型定义函数或类,而STL通过通用算法更进了一步。模板让这一切成为可能。
  3. STL三大组件:容器,算法,迭代器;(算法操作数据,容器存储数据,迭代器是算法操作器的桥梁,迭代器和容器一一对应)
  4. STL几乎所有的代码都采用了模板或模板函数。
    在这里插入图片描述

三、STL六大组件

六大组件:

  1. 容器:各种数据结构,是一个概念化的抽象基类,容器不真正使用继承机制,容器概念指定了所有STL容器类都必须满足的一系列要求。如:vector,list,deque,set,map等,用来存放数据;
  2. 算法:各种常用的算法,如:sort,find,copy,for_each等;
  3. 迭代器:容器和算法直接的桥梁;
  4. 仿函数:为算法提供更多的策略;
  5. 适配器:为算法提供更多的参数接口;
  6. 空间适配器:管理容器和算法的空间;

四、STL中容器,算法,迭代器

1.容器:容器是存储其他对象的对象,被存储的对象必须是同一种类型的,它们可以是面向对象意义上的对象,也可以是内置类型值。STL容器就是将运用最广泛的一些数据结构实现出来,常用的数据结构:数组,链表,树,队列,集合,映射表等;容器分为:序列式容器和关联式容器:
在这里插入图片描述

不能将任何类型的对象存储在容器中,类型必须是可复制构造的和可赋值的。基本类型满足。 类定义没有将复制构造函数和赋值运算符声明为私有或保护的,也满足。 c++11改进了这些概念,添加术语可复制插入和可移动插入。

基本类型不能保证其元素都按特定的顺序存储,也不能保证元素的顺序不变,但概念进行改变进行后,则可以增加这样的保证。

所有的容器都提供某些特征和操作。下表是一些特征进行了总结。X:容器;T:对象类型;a,b:类型为X的值;r:类型为X&的值;u:类型为X的标识符
在这里插入图片描述

五、C++11新增的容器种类

下图列出新增的通用容器要求,rv表示类型为X的非常量右值,如函数的返回值。另外,要求X::iterator满足正向迭代器的要求,而以前只要求它不是输出迭代器。在这里插入图片描述
复制构造和复制赋值以及移动构造和移动赋值之间的区别在于,复制操作保留源对象,而移动操作可修改源对象,还可能转让所有权,而不做任何复制。如果源对象是临时的,移动操作的效率将高于常规复制。

六、序列

  1. 添加要求来改进基本的容器概念。序列就是重要的改进。因为STL(deque,forward_list,list,queue,priority_queue,stack,vector,array(虽然不满足序列要求))都是序列。
  2. 序列概念增加迭代器至少是正向迭代器这样的要求,保证元素按特定顺序排列。
  3. 序列要求元素按严格的行线顺序排列,即存在第一个元素和最后一个元素,除第一和最后元素外,每个元素前后都分别有一个元素。数组和链表都是序列,分支结构不是。
  4. 序列都有确定的顺序,因此可以执行诸如将值插入到特定位置,删除特定区间等操作。

下表列出这些操作以及序列必须完成的其他操作。(t:类型为T的值,n表示整数,p,q,i,j:迭代器
在这里插入图片描述

模板类deque,list,queue,priority_queue,stack,vector都是序列概念的模型,所以都支持上表的运算符。且还可以使用其他操作。
在这里插入图片描述
注:

a[n]和a.at(n)都返回一个指向容器中第n个元素的引用,之间区别在于,如果n落在容器的有效区间外,则a.at(n)将指行边界检查,引发out_of_range异常。

为什么vector没有定义push_front(),假设将一个新值插入到变化100个元素的矢量的最前面,必须将第99个移100,把98移到99,依次类推,这种操作的复杂为线性时间,因为移动100个元素时间是单个的100倍,但表中操作被假设为仅其复杂度为固定时间才被发现。

链表和双端列队列的设计允许将元素添加到前端,而不用移动其他元素,所以它们以固定时间的复杂度来实现push_front()

七、算法

有限的步骤,解决逻辑或数学上的问题,叫算法,算法分为:质变算法和非质变算法。

  1. 质变算法:是指运算过程中会更改区间内的元素的内容。例如:拷贝,替换,删除等等。
  2. 非质变算法:是指运算过程中不会更改区间内的元素内容,例如:查找,计算,遍历,寻找极值等等。
八、迭代器

迭代器是STL的关键,模板使得算法独立于存储的数据类型,而迭代器使算法独立于使用的容器类型,因此,都是STL通用方法的重要组成部分。迭代器能够用来遍历容器的对象,与能够遍历数组的指针类似,是广义指针。

1.迭代器的种类

在这里插入图片描述

2.随机访问迭代器

X:随机迭代器类型;T:指向的类型;a,b:迭代器值;n:整数;r:随机迭代器变量或引用。在这里插入图片描述有些算法要求能够直接跳到容器的任何一个元素,这叫随机访问,需要随机迭代器。随机访问迭代器具有双向迭代器的所有特性,同时添加了支持随机访问的操作和用于对元素进行排序的关系运算符。上图也支持随机访问迭代器。

3.迭代器层次结构

迭代器类型形成了一个层次结构。正向迭代器具有输入迭代器和输出迭代器的全部功能,同时还有自己的功能。双向迭代器具有正向迭代器的全部功能,同时还有自己的功能;随机访问迭代器具有正向迭代器的全部功能,同时还有自己的功能。下图总结了主要迭代器功能:i:迭代器;n:整数;
在这里插入图片描述
注:各种迭代器的类型并不确定,而只是一种概念性叙述。

九、概念,改进和模型
  1. 概念可以具有类似继承的关系。例如:双向迭代器继承了正向迭代器的功能。
  2. 不能将c++继承机制用于迭代器。例如:可以将迭代器实现一个类,而将双向迭代器实现为一个常规指针。因此,对C++而言,这种双向迭代器是一种内置类型,不能从类派生而来。
  3. 概念上看,STL确实能够继承,有些STL文献使用术语改进来表示这种概念上的继承,因此,双向迭代器是对正向迭代器概念的一种改进。
  4. 概念的具体实现被称为模型。因此,指向int的常规指针是一个随机访问迭代器模型,也是一个正向迭代器模型,因为它满足该概念的所有要求。
十、将指针用作迭代器

迭代器是广义指针,而指针满足所有的迭代器要求。迭代器是STL算法的接口,而指针是迭代器,因此STL算法可以使用指针来对基于指针的非STL容器进行操作。
例如:可将STL算法用于数组,假设Receipts是一个double数组,并要按升序对它进行排序:

const int SIZE=100;
double Receipts[SIZE
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值