【博览网】C++标准库——第四周课程笔记

第四周的课程继续介绍标准库的内容,本周主要介绍了STL中的算法和适配器。详细讲解了迭代器中的traits如何帮助算法获得更高的性能,也介绍了适配器如何通过改造其适配对象,使适配对象取得所需的特殊行为。这一部分的内容比较复杂,重点放在算法和适配器的使用上,而不是构造上。

一、算法与迭代器
1.算法的基本形式
在STL中,算法主要是以模板函数的形式存在,在调用时,需要向模板函数中传入迭代器以及需要进行的处理函数指针or仿函数。在算法调用时,对不同类型的数据结构,可以使用不同的算法进行计算,这样可以提高程序效率。因此,迭代器中会记录自身的相关信息,供算法在调用时进行查询使用。算法所能知道的所有信息都是来自于迭代器。
2.迭代器的分类
这里写图片描述
迭代器按照上图的继承体系分为5个类别,分别为:
• output_iterator_tag:只写迭代器,只能写数据和向后移动。
• input_iterator_tag:只读迭代器,只能读数据和向后移动。
• forward_iterator_tag:单向迭代器,可读可写,只能向后移动。
• bidirectional_iterator_tag:双向迭代器,可读可写,可向前或者向后移动。
• random_access_iterator_tag:随机迭代器,可读可写,可以在常数时间内随机访问范围内的任意元素。
3.迭代器分类对算法的影响
主要体现在两方面,一是部分算法只能传入特定迭代器,其他迭代器传入会报错或者运行效率非常低,比如sort函数便只能传入随机迭代器。二是算法对于特定的迭代器可能有更加快速的计算方法,如distance函数对于普通的迭代器只能使用“++”一步一步去计算两个迭代器的距离,但是对于随机迭代器,该算法便可以直接调用“-”计算距离,效率更高。那么,算法是如何实现这种区分的呢?
这里写图片描述
如图,算法在执行时会调用一个辅助函数,这个辅助函数往往有几个重载版本,重载版本的不同的参数对应着一饿tag类型,主调用函数通过创建一个临时的tag类型实现函数根据迭代器类型决定不同的算法实现方法。

二、仿函数
仿函数是一种特殊的class或者struct,它通过重载()运算符来模拟函数指针的行为。在STL中,如果仿函数需要应用在函数适配器中,则需要继承对应的函数适配器类。如下图所示:
这里写图片描述
继承了适配器类后,函数适配器便可以使用该类型萃取出对应的参数,用于检查参数类型等工作,具体方式将在适配器部分介绍。

三、适配器
在STL中有多种类型的适配器,所有类型的适配器都是使用“内涵”的方式实现的。
1.容器适配器
典型的容器适配器包括stack、queue等,在容器部分已经介绍了,因此在此不作过多说明。
2.函数适配器
函数配适器是用于改变函数行为的配适器类,常见的函数配适器有参数绑定函数、否定函数等。前面提到过,如果一个仿函数如果需要能够被函数配适器配适,则需要继承包含参数重命名的基类。这是因为,在函数配适器中,需要通过基类来萃取传入的仿函数的参数信息。萃取的原理与traits类似。
3.迭代器适配器
迭代器适配器通过重载对应的成员函数,改变迭代器的行为。最典型的迭代器配适器是反向迭代器。
反向迭代器的原理是要模拟反向进行的迭代器,其实现的关键是成功的模拟出迭代器前闭后开的特征。因为反向迭代器常常用于将特定区间进行反向处理,因此这一点十分重要。其模拟效果如下图所示:
这里写图片描述
另一个比较典型的迭代器配适器是inserter配适器,这个迭代器主要应用于copy函数中。我们知道,正常的copy函数是将前两个迭代器参数区间内的元素复制到以第三个迭代器开头的一片空间中,在copy算法内部,直接将目标区域的迭代器所指区域的内存覆盖,不会再额外分配内存,因此算法原始的复制方式会存在一定的安全隐患。如果使用inserter配适器修饰迭代器,再调用copy函数,inserter会在迭代器所指的位置后分配空间来存储复制过来的元素。实现这一功能是通过重载函数实现的。
这里写图片描述
上图展示了copy内部的核心函数内容,可见,要实现上述的内容,需要重载几个函数,分别为*,=,++,以及拷贝构造函数。
这里写图片描述
上图展示了一些内部的实现细节,在inserter内部维持了对容器和迭代器的指针,这是为了在赋值时使用容器的inserter函数插入对应数据。
4.两个特殊的配适器
在STL中有两个十分特别的配适器,ostream_iterator和istream_iterator。这两个配适器可以封装输出流和输入流,通过调用copy函数将迭代器区间内的数据打印到流中,或者将流中的内容复制到迭代器中。这两个配适器模拟了迭代器的行为,但是本身却不是迭代器配适器。因此可以说是非常特殊的配适器。其实现方法与前面的inserter类似,以下有其关键源代码:
这里写图片描述
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值