近日在看《STL源码解析》,STL里面一大堆泛型编程的确是非常巧妙,不过由于时间有限,我还是只能更加专注于日常使用比较多的一些知识。

Adapter是我在最开始使用STL Container的时候就听到的一个词,一直以来没有比较深入的了解,借着这次学习STL源码,在这里总结一下:

首先是Adapter的定义,《Design Patterns》中对于Adapter的定义我觉得真的十分准确:将一个Class的接口转换成另一个Class的接口,使原本因接口不兼容而不能合作的Class可以一起运作。这很直接就能让我想到日常生活中常见的Adapter:电源适配器。同样的,其实两者的作用也差不多。

STL里面主要有两种接配器(Adapter):容器接配器(Container Adapter)和迭代器接配器(Iterator Adapter),下面举几个例子了解一下这两类主要的Adapter:

Container Adapter:

  最常用的容器接配器无非是queue和stack,从意义上来说,他们为底层的容器提供了一层包装,使得底层的容器只表现出这些接配器所定义的数据结构的功能。

这里假设底层容器是deque,双向开口,而且两端插入删除都能够实现O(1)的时间复杂的。当作为queue进行包装的时候deque就会封闭一端的插入操作,封闭另一端的删除操作,使得整个deque表现出FIFO的特性,在作为stack的时候同理。

  可以看到Container Adapter做到的功能很直观,也很好理解,只是对于容器的一层包装,改变了数据结构的接口的同时方便了我们对其的理解和使用。

Iterator Adapter(#include<iterator>)

  迭代器接配器是我原先并不是很熟悉的,对于STL中iterator的使用我可能最多的也就是begin(),end(),const_iterator,rbegin()等等,而在这里我要讲的Iterator Adapter主要有三种,分别是insert iterator,reverse iterator,iostream iterator。

  首先是insert iterator。从定义上来讲,它的作用是将一般迭代器的赋值(assign)操作转变为插入(insert)操作。理解了这句话也就理解了insert iterator的本质。

下图显示的是STL里面insert iterator的主要用法:

  这三种形式的最大区别无非就是使用Adapter之后元素插入的位置了。

  先来一段最简单的测试代码:

 1 #include<iostream>
 2 #include<iterator>
 3 #include<vector>
 4 using namespace std;
 5
 6 int main(){
 7     vector<int> data={6,2,3,4,5,9};
 8     for(int i = 0;i<10;++i){
 9         *back_inserter(data)=i;
10     }
11
12     for(auto j:data) cout<<j<<" ";
13     cout<<endl;
14     return 0;
15 }

输出结果:6 2 3 4 5 9 0 1 2 3 4 5 6 7 8 9

可以看到,我们依然可以把经过Iterator Adapter修饰之后的结果当成是一种迭代器,依然可以用*符号,但不同的是当你对它进行赋值的时候,它将自动进行insert操作。使用原书中的描述应该更好:

也就是说在insert iterator的封装下,该iterator只是将assign操作变成了push_back,push_front,insert,而其他操作++,--,*全部返回原先的iterator

这也就能够解释copy函数的时候进行复制的底层实现了,在每复制一个值后的++对insert iterator并不起作用,只有赋值assign会起到相关操作。

当使用copy函数的时候:

 1 #include<iostream>
 2 #include<iterator>
 3 #include<vector>
 4 #include<algorithm>
 5 using namespace std;
 6
 7 int main(){
 8     vector<int> data={6,2,3,4,5,9};
 9     vector<int> res={2,1,1};
10     copy(data.begin(),data.end(),back_inserter(res));
11     for(auto j:res) cout<<j<<" ";
12     cout<<endl;
13     return 0;
14 }

输出结果:2 1 1 6 2 3 4 5 9

copy的时候每次都是从res的末尾插入一个数字并进行copy,而不像copy本义中只存在的赋值而已。

  reverse iterator:

  显然作用是使得iterator方向相反,常和rbegin,rend一起使用,比如:

 1 #include<iostream>
 2 #include<iterator>
 3 #include<vector>
 4 #include<algorithm>
 5 using namespace std;
 6
 7 int main(){
 8     vector<int> data={6,2,3,4,5,9};
 9     vector<int>::reverse_iterator it = data.rbegin();
10     for(;it!=data.rend();++it) cout<<*it;
11     cout<<endl;
12     return 0;
13 }

输出:954326

  iostream iterator:

  这种Adapter将iterator和输入输出流(可以是文件流)相关联,经常和copy函数联合使用:

 1 #include <iostream>     // std::cout
 2 #include <iterator>     // std::ostream_iterator
 3 #include <vector>       // std::vector
 4 #include <algorithm>    // std::copy
 5
 6 int main () {
 7   std::vector<int> myvector;
 8   for (int i=1; i<10; ++i) myvector.push_back(i*10);
 9
10   std::ostream_iterator<int> out_it (std::cout,", ");
11   std::copy ( myvector.begin(), myvector.end(), out_it );
12   return 0;
13 }

输出:10, 20, 30, 40, 50, 60, 70, 80, 90,

从上面的例子中可以看到,接配器(Adapter)在STL中有着重要作用,其和copy等常用函数关系紧密,同样可以和输入输出等操作进行结合。  

参考:《STL源码剖析》

  http://www.cplusplus.com/reference/iterator/ostream_iterator/

转载于:https://www.cnblogs.com/J1ac/p/9025175.html

C++ 接配器(Adapter)总结相关推荐

  1. java设计模式--设配器adapter

    今天一大早,你的leader就匆匆忙忙跑过来找到你:"快,快,紧急任务!最近ChinaJoy马上就要开始了,老板要求提供一种直观的方式,可以查看到我们新上线的游戏中每个服的在线人数.&quo ...

  2. android实现文本输入,Android实现智能提示的文本输入框AutoCompleteTextView

    今天我们要讲一个十分简单的内容,就是一个安卓控件的使用,用法很简单,但是很常用的一个.这里我用两种不同的写法来处理.当然,无论用哪一种写法,效果都是一样的. 我们先来看效果图. 要实现这种效果十分简单 ...

  3. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

  4. ListView通过自定义的Adapter实现异步下载显示网络图片

    为什么80%的码农都做不了架构师?>>>    先说一下思路,开始让一张放在res/drawable里的图片代替网络图片,加进ListItem,现在显示的就是本地图片,然后新开一个线 ...

  5. Adapter(适配器)--类对象结构型模式

    Adapter(适配器)–类对象结构型模式 一.意图 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本接口不兼容而不能一起工作的那些类可以一起工作. 二.动机 1.在软件系统中, ...

  6. 设计模式七:Adapter(适配器)——类对象结构型模式

    结构型模式: 结构型模式设计到如何组织类和对象以获得更大的结构. 结构型类模式: 采用继承机制来组合接口或实现.简单的例子是采用多重继承,这一模式尤其有助于多个独立开发的类库协同工作. 结构型对象模式 ...

  7. 设计模式:设配器模式

    设配器模式 1.泰国旅游使用插座问题 现实生活中的适配器例子 泰国插座用的是两孔的(欧标),可以买个多功能转换插头 (适配器) ,这样就可以使用了. 2.适配器模式基本介绍 适配器模式(Adapter ...

  8. 设计模式--设配器模式

    设配器模式 现实生活中的适配器例子: 泰国插座用的是两孔(欧标),可以买个多功能转换插头(适配器),这样就可以使用了. 基本介绍 设配器模式将某个类的接口转换成客户端期望的另一个接口表示,主要的目的是 ...

  9. Java 設計模式 - 適配器模式

    Java 設計模式 - 適配器模式 適配器模式前言 模式概述 模式結構 模式具體應用 類適配器模式 對象適配器模式 優缺點 適配器模式前言 在現實生活中,經常出現兩個對象因接口不兼容而不能在一起工作的 ...

最新文章

  1. Windows XP Service Pack 3 RC2 简体中文版发布
  2. 物理机Windoes上运行VWware 虚拟机连接外部物理机、外部网络的方法
  3. PIC单片机 电容式触摸检测
  4. 从零开始学习jQuery (六) AJAX快餐
  5. StackExchange.Redis 访问封装类
  6. sqlite 模糊匹配日期_SQLite模糊查找(like) | 学步园
  7. mongo 修改器 $inc/$set/$unset/$pop/$push/$pull/$addToSet
  8. 医药公司java,医药管理系统java版
  9. SylixOS Makefile 源代码解析
  10. 图片验证码实现的几种方式
  11. Android Studio在运行时显示Please Select Android SDK的解决方法
  12. 逻辑面试题:猴子搬香蕉
  13. 20200415 计算机的基础之host配置
  14. 嫡权法赋权法_客观赋权法的使用
  15. 激活后服务器无限重启,服务器无限重启
  16. android学习总结(16.08.29)进度条控件ProgressBar和ProgressDialog
  17. 自定义身份证输入键盘
  18. IDEA常用配置汇总
  19. 规范化理论:如何求属性集X关于F的闭包?
  20. 春节荐书 | 2019年我读过的十本好书

热门文章

  1. MyEclipse中阿里JAVA代码规范插件(P3C)的安装及使用
  2. C语言迷宫问题大全,c语言实现迷宫问题
  3. chrome浏览器保存mht网页文件的方法
  4. mysql初始密码的获取以及修改超级用户密码的方法
  5. shuf 命令: 随机排序文件
  6. 遥感影像深度学习标注软件的开发要点
  7. 运维实操——zabbix监控结合tidb分布式数据库
  8. CSP 202112-1 序列查询
  9. 数据库SQL习题练习Day7
  10. Python利用mask提取保存图片前景