系列文章目录
C++基础:开篇
C++基础1:从const关键字看变量的基础单元-类
C++基础2:构造函数、拷贝构造、赋值运算符重载
C++基础3:仿函数
文章目录
前言
函数适配器技术可以在不修改源代码的基础上,增加函数的功能。是对面向对象开闭原则的体现。在C++ STL中就是用了大量的函数适配器,比如not1。
一、函数适配器是什么?
简单来说函数适配器就是基于原有函数功能的基础上,再增加一些功能。跟pointer like class有些相似,都是想在原有的功能上,做更多的事情。
二、实现函数适配器
1.定义函数
代码如下:
class RealTrue
{
bool operator()(bool flag)
{
return flag;
}
}
我们定义了一个仿函数类,该类很简单,就是把传入的flag,直接返回。
2.定义函数适配器
代码如下:
class RealTrueAdaptorNot
{
protected:
RealTrue opt;
public:
RealTrueAdaptorNot(RealTrue x) : opt(x){}
bool operator()(bool flag)
{
return !opt(flag);
}
}
该适配器的功能是在原有功能的基础上,取反。
3.使用函数适配器
代码如下:
#include <iostream>
using namespace std;
int main()
{
RealTrue rt;
RealTrueAdaptorNot not_rt(rt);
cout << not_rt(true) << endl;
return 0;
}
输出结果就为false。
有人会说,就这儿??? 不就加了个取反符号嘛。而且只能修饰RealTrue类。
我说 如果只是这样,函数适配器确实弱了一点。但是函数适配器再加上模板,就很厉害了。
下面我们试一下。
3.带模板的函数适配器
代码如下:
template <typename operation>
class AdaptorNot
{
protected:
operation opt;
public:
AdaptorNot(operation x) : opt(x){}
bool operator()(bool flag)
{
return !opt(flag);
}
}
这样的话,所有符合以下条件的类,都可以用AdaptorNot类修饰。
1.实现了operator()的重载。
2.operator()的重载函数是如下的声明格式:
bool operator()(bool 形参名字)
有人又要说,我的形参不是bool类型的,AdaptorNot就无法修改了吧。
这确实是个问题,不过STL给出了一种解决方案。 提供了unary_function类。
下面我们仿照STL,做一个自己的unary_function类。
4.自定义unary_function
代码如下:
template <typename arg,typename res>
struct my_unary_function
{
typedef arg argument_type;
typedef res result_type;
}
5.改写带模板的函数适配器
代码如下:
template <typename operation>
class AdaptorNot
{
protected:
operation opt;
public:
AdaptorNot(operation x) : opt(x){}
bool operator()(typename operation::argument_type flag)
{
return !opt(flag);
}
}
6.自由参数类型调用函数适配器
代码如下:
class my_less_five : public my_unary_function<int,bool>
{
public:
bool operator()(int x)
{
return x<5;
}
}
int main()
{
my_less_five less5;
AdaptorNot<my_less_five> not_less5;
count << not_less5(3) << endl;
}
这里的奥义是:只要类继承了my_unary_function类,就可以被AdaptorNot适配。
C++ STL中的函数适配器就是这个原理,只不过它用模板函数又包了一层,用起来更方便了。
总结
以上就是今天要讲的内容,函数适配器是STL很重要的一部分,遍历集合函数中的条件语句,用到了很多的函数适配器。