STL配接器

配接器

一.配接器概论

配接器是什么,按正规的定义来说,就是将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes可以一起运作,通俗的说,就是转换接口来适配其他调用者,例如把需要两个参数的转换成一个参数的就行。

配接器补充定义:修饰某种事物的接口成为另一种接口以呈现出不同的事物。

二.配接器分类

有function adapter(仿函数配接器),container adapter(容器配接器),iterator adapter(迭代器配接器)。

1.container adapter

STL中的queue和stack都是配接器,通过修饰deque而呈现另一种容器。

2.iterator adapter

STL中还是定义了一些迭代器配接器,这些配接器的接口可以由获得。

注意:iterator adapter不像functor adapter那样直接以仿函数作为参数,而是以容器作为参数,从而间接的以容器里的迭代器作为参数。

Insert Iterator

所谓insert iterator,可以将一般迭代器的赋值操作转变为插入操作,这样的迭代器有专门负责尾端,头端,任意位置插入的三个迭代器,但这三个迭代器并不直观,因此用三个辅助函数配接这三个迭代器使得更易使用。

Reverse Iterator

所谓reverse iterator就是将一般迭代器的行进方向逆转,opertor++变成后退,operator–变成前进,适用于从尾端开始的算法。

IOStream Iterator

所谓 iostream iterator是把迭代器绑定到某个iostream对象身上,从而使得拥有输入功能和输出功能。

3.functor adapters

functor adapters是数量最大的配接器族群,因为它非常灵活,可以执行如系结(bind),否定(negate),组合(compose),对一般函数或成员函数的修饰使其成为一个仿函数等操作,这些操作可以灵活使用,使得我们可以利用functor adapters方便地做出我们想要的东西。

functor adapters最大的价值就在这一点:通过它们之间组合,绑定,修饰的能力创造出各种可能的表达式。

functor adapters可以修饰一般函数和成员函数使得接口变为仿函数从而使得STL算法可以使用这些函数。

特别注意,所有希望获得配接能力的组件本身要满足配接要求,即上一章中所说的要有相应的类型,因此仿函数本身必须继承了那两个类,成员函数必须经过mem_fun处理,一般函数必须经过ptr_fun处理。

三.具体实现

1.container adapters

stack和queue都是作用于deque上的配接器,都封闭了deque的对外接口,只保留自己要用到的几个函数。

2.iterator adapters

下面是三种迭代器配接器的完整实现

insert iterator

主要实现观念为:每一个迭代器配接器内部有一个关联的容器,使用重载和容器本身自有的功能将赋值操作变为插入操作,注意迭代器配接器外部表现还是一个迭代器,只是内部将赋值操作变为了容器的插入操作,其他功能如++,–,*等均被关闭,改为返回配接器本身(这一点是有用的)。所以insert iterator主要用于利用迭代器赋值的地方,需要与一个容器绑定。

reverse iterator

这是个很神奇的配接器,与一个迭代器绑定,表现得也像一个迭代器,主要功能是实现迭代器的逆向移动,为了实现这一功能,首先取值的时候需要往左取,这样才能维持区间的左闭右开,同时还需要对一些列移动操作重载,使得方向逆反。很多容器本身也有rbegin和rend的函数功能来获得自身的逆转配接器。

stream iterator

所谓stream iterator与一个iostream绑定,表现的还是像一个迭代器,主要功能是实现读入或读出。

首先说istream iterator,在其中绑定一个istream,当迭代器++的时候执行读入操作。有两种初始化操作,一种是没有参数的初始化,这种情况下配接器里面的eos被初始化为false,这个主要是用来判断另一个istream iterator读入结束没有(即++有没有到终点),另一种是有参数的初始化,参数为一般为cin,有了参数之后立马执行read然后阻塞直到有数据输入(所以用这个要小心),输入直到遇到eof或类别不同的数据,还有就是这个配接器++的时候是执行read,还有*的时候是返回读入的value。

然后说ostream iterator,其中也是绑定了一个ostream,当迭代器被赋值(=)的时候执行输出操作,当被赋值时,首先输出赋的值,然后输出初始化后的string,执行其他操作返回的是自身。

正如书上所说,这两种迭代器配接器为我们展示了如何量身定制一个迭代器配接器,展示了一个更大的世界。

3.function adapters

所谓函数配接器,是指与一个函数绑定,里面这个函数要是可绑定的(即拥有相应得到型别),同上面的一样,STL中也已经定义了一些函数配接器,而要被这些函数配接器配接,那么相应的函数必须满足相应的型别,函数配接器最终表现得像函数一样。

看一下下面的not。

接下来就介绍一些函数配接器。

not1,not2(对返回值进行逻辑否定)

这个配接器其实就体现函数配接器的全过程:首先将某个函数作为参数,然后在配接器内部对函数执行想执行的操作,中间当然也要用到重载来使得配接器本身表现的像一个仿函数一样。具体的not本身没有什么好说的,就是绑定一个本身返回bool值的可配接的函数,然后在函数重载中对结果取反再返回。

bind1st,bind2nd(对参数进行绑定)

这个配接器首先还是绑定一个函数,然后在配接器内部先绑定好第一个或第二个参数,然后具体调用的时候只用传入第二个或第一个参数即可。

compose1,compose2(用于函数合成)

这个也比较简单,传入两个或三个函数,然后根据规则对这些函数进行组合。

ptr_fun(用于函数指针)

这个也比较简单,只要你略懂函数指针的定义,ptr_fun的功能就是将一般的函数转化为仿函数使用,同时使得配接后的函数也考验继续配接。

参考:stl中的ptr_fun的实现

mem_fun,mem_fun_ref(用于成员函数指针)

这个的作用就是将成员函数转化为仿函数并且能够继续配接,如果容器的元素是指针或引用的话还可以利用配接虚函数实现多态。

具体的实现也是封装成员函数的指针在配接器中,然后在重载函数中要么用指针要么用引用来使用这个函数指针。我觉得这个最不同的就是之前是把函数转换为仿函数然后使用这个函数,而成员函数转换为仿函数后在重载里面还是要由一个类来调用,当然也可以有参数。差不多,其实认真看的话还是比较简答。

四.小结

配接器就是封装一个东西然后表现出另一种东西的东西(有点绕哈哈),例如封装了容器表现出插入的迭代器,封装了迭代器表现出逆转的迭代器,封装了容器表现出另一种容器,封装了函数表现出仿函数。注意,配接器最后不一定要表现为仿函数,即不一定要利用()重载,还可以有其他的使用方式。这一章认真看还是不难。

至此,这本书算是看完了第一遍,挺难得的,可能以后还会再看吧,到时候再看一下这些笔记。

路漫漫其修远兮,吾将上下而求索。道阻且长啊,下面就该看《Linux高性能服务器编程》了,加油吧,今晚吃点好的哈哈。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值