一般只有一个私有成员变量(某物)的类,且其全部的成员函数都是对该唯一的成员变量的存、取和修改(实现修改某物接口,形成另一种风貌,侯捷语),则该类即为对该私有成员变量的配接(adapter)。
Adapter 这一概念,也是一种设计模式(design pattern),《Design Patterns》对 Adapter 设计模式的定义如下:将一个 class 的接口转换为另一个 class 的接口,使原本因接口不兼容而不能合作的 classes,可以一起运作。一言以蔽之,Adapter 用于改变接口。
STL 主要提供如下三种配接器:
- (1)改变仿函数(functors)接口,称之为 function adapter
- (2)改变容器(containers)接口,称之位 container adapter
- (3)改变迭代器(iterators)接口者,称之为 iterator adapter
一、应用于容器,container adapter
STL 提供的两个容器 queue 和 stack,其实都不过是一种配接器,是对 deque (双端队列)接口的修饰而成就自己的容器风貌。如果按照该标准衡量其他容器的话,序列式容器的 set 和 map 其实是对其内部所维护的 RB-tree 接口的改造:
- (1)deque:stack、queue
- (2)RB-tree:set、map
二、应用于迭代器,iterator adapter
源码之前,了无秘密(一)——iterator adapter
STL 提供的应用于迭代器身上的配接器,这些接口所在的头文件为<iterator>,主要包括:
(1)insert iterators
- 所谓 insert iterators,可以将一般迭代器的赋值(=,assign)操作变为插入(insert)操作。
- 这样的迭代器包括专司尾端插入操作的 back_insert_iterator,专司头端插入的 front_insert_iterator,以及可在任意位置执行插入操作的 insert_iterator。
- 由于这三个 iterator adapters 的使用接口不太直观,给一般用户带来困扰,STL 提供三个相应函数,back_inserter()、front_inserter()、inserter()
对于第一点,赋值变插入,可通过 front_inserter() 的源码以清晰地显示:
template<class _Container> inline front_insert_iterator<_Container> front_inserter(_Container& _Cont) { // return front_insert_iterator return (_STD front_insert_iterator<_Container>(_Cont)); } template<class _Container> class front_insert_iterator : public _Outit { typedef front_insert_iterator<_Container> _Myt; typedef _Container container_type; typedef typename _Container::value_type _Valty; // 真正的赋值操作在这,它首先进行的是push_front // 自然从 赋值 变成了 插入 // 显然 front_inserter 的参数必须是支持 push_front 成员方法的容器, // vector 容器就不符合要求 _Myt& operator=(const _Valty& _Val) { // push value into container container->push_front(_Val); return (*this); }
(2)reverse iterators
(3)iostream iterators
- istream_iterator
- ostream_iterator
三、应用于仿函数,functor adapter
functor adapters(亦称为 function adapters)是所有配接器中数量最为庞大的一个族群,其配接灵活程度也非前二者所能及,可以配接、配接、再配接。这些配接操作包括,
- (1)系结(bind)、否定(negate)、组合(compose),
- (2)以及对一般函数或成员函数的修饰(使其成为一个仿函数)
C++ Standard 规定这些配接器的接口可由 <functional> 获得;