Java教程

16 适配器

本文主要是介绍16 适配器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

adapter 适配器

在这里插入图片描述

  1. 迭代器适配器 与算法合作 迭代器的5 个typedef
  2. 容器适配器 : stack, queue, map, set, multimap, multiset, unordered_set, unordered_multiset, unordered_map, unordered_multimap
  3. 仿函数适配器 与算法合作

设计模式:adapter

适配器的实现

a -> b

  1. 继承方式 (不使用)
  2. 组合方式 yes

容器适配器

容器适配器:stack, queue

内含一个sequence: deque

在这里插入图片描述

函数适配器

何时绑定?调用时绑定。第二个参数类型如何确定?通过辅助模版函数类型推导获得

​ () 到底是函数调用? 还是在创建对象?

​ 把东西记起来,等着以后调用

在这里插入图片描述

cout << count_if(vec.begin(), vec.end(), not1(bind2nd(less<int>() , 40))) <<endl; 

binder2nd

  1. Bind2nd 将第二个参数绑定为指定的参数, less () 是一个对象,传给bind2nd,
  2. 40也传给了bind2nd,并且依靠辅助函数进行类型推导。binder2nd
  3. Bind2nd 修饰functor,修饰之后也要表现为functor
  4. 在被调用的时候才有绑定第二个参数的动作发生。
  5. binder2nd是个类模版-》主体,因为模版参数是Operation
  6. 对外界的接口是bind2nd 函数模版可以做参数推导,获得op类型和x的类型 Operation, T
  7. 这两个参数传给构造函数,将x记录在op中,y记录在value中。生成对象。传给count_if使用

细节:

  1. 灰色部分:问和答
    1. arg2_type 是什么类型 arg2_type(x) 在编译时通过表示可以转换,如果不能通过则编译时错误,而不是runtime-error
    2. 返回的是什么类型? Typename Operation::result_type
    3. 第一个实参是什么类型? const typename Operation::first_argument_type
    4. 为什么要加上typename? 帮助编译器通过这行代码是不应该通过的,让编译器能通过
  2. 继承的typedef
    1. 如果binder2nd 也想要被适配的话,也要继承unary_function,才能回答两个问题:实参和返回类型

已经被bind取代了

在这里插入图片描述

not1

在这里插入图片描述

bind

bind 的实现相当的复杂。

Std::bind 可以绑定:

  1. 函数
  2. 仿函数
  3. 成员函数
  4. 类数据成员

在这里插入图片描述

使用占位符:using namespace std::placeholders

对象后面 {} 赋初值

在这里插入图片描述

​ 绑定第一个参数是成员函数,由于成员函数有一个隐藏的this指针,需要将对象传入以获得正确的this指针,所以用占位 _1来占位,真正调用bind的时候将对象传进去

迭代器适配器

在排序的时候使用过,实现的时候要注意不要越界。

排序默认是less ,但是传入的迭代器是逆向的,那么输出的就是降序排列

reverse_iterator 操作符重载

在这里插入图片描述

  • 逆向迭代器的5种typedef与正向迭代器相同
  • 对逆向求值就是对正向退一步求值
  • 先看对象重载解引用操作符: 先–,再解引用
  • 后置改为前置

inserter 操作符重载

在这里插入图片描述

  • 当容器size不足时,copy可能会导致溢出,因为copy不会考虑目的空间是否足够
  • inserter 会负责insert操作,并且将iterator 右移一个位置,这样就可以连续执行表面上assign实际上insert的行为
  • 在3,4中间,插入元素。copy中的代码已经写好,不能变了,将目的端迭代器改为inserter

源码:

​ inserter辅助函数 进行类型推导。

​ assign 操作符重载,改变行为

  1. 先调用容器的插入算法,返回插入的位置给 iter
  2. ++iter使得ite指向刚插入的元素位置
  3. 返回给调用者,可以继续进行插入操作。

X 适配器 ostream_iterator 重载了什么?

在这里插入图片描述

  1. 第一个参数绑定了cout, 第二个参数传入字符串作为分隔符。
  2. copy的源代码是固定的,因为有操作符重载,所以行为不同。
    1. 解引用,
    2. 赋值。
    3. ++
    4. 最后返回,会调用拷贝构造函数
  3. 这些动作最后能传给cout中

源码

  1. 构造函数,观察传进去的值是啥: s, dilimiter
  2. 解引用操作符,返回自身的引用
  3. 赋值运算符
    1. *out_stream << value;
    2. 如果占位符不为空,*out_stream << delimiter;
    3. return *this; cout是全局对象,只有一个。
  4. 前置,后置++ 返回自身的引用
  5. 对out_stream迭代器改造:将字符串输出到屏幕上

X 适配器: stream_iterator 做了些什么

在这里插入图片描述

  1. eos表示输入状态结束了
  2. iit 调用的有参数构造函数
    1. 构造过程中++
    2. ++运算符重载:等待输入 阻塞
    3. != 运算符
    4. 解引用操作符重载: 将读取成功的值返回
    5. ++iit 再读一次,阻塞等待键盘输入
  3. input 是 basic_istream 可以是cin 也可以是文件等
  4. 对迭代器不断++相当于不断读内容

在这里插入图片描述

与copy一起使用

必须定义操作符,来适配已经写好的copy的动作

  1. 在创建iit对象的时候就开始读输入
  2. !=
  3. ++
  4. return 引发的拷贝构造函数

意义和价值

  1. 6大部件的实现
  2. 数据结构
  3. 模版在使用的时候,一旦用错了,会报出很多的错误信息,读源码有利于使用STL
这篇关于16 适配器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!