C++仿函数(functor)详解

  所谓的仿函数(functor),是通过重载()运算符模拟函数形为的类。

  因此,这里需要明确两点:

  1 仿函数不是函数,它是个类;

  2 仿函数重载了()运算符,使得它的对你可以像函数那样子调用(代码的形式好像是在调用

函数)。

  看下面的实例:

#include <iostream>

using namespace std;

const int CMP_LES = -1;

const int CMP_EQU = 0;

const int CMP_BIG = 1;

class Comparer

{

public:

Comparer(int cmpType)

{

m_cmpType = cmpType;

}

bool operator ()(int num1, int num2) const

{

bool res;

switch(m_cmpType)

{

case CMP_LES:

res = num1 < num2;

break;

case CMP_EQU:

res = num1 == num2;

break;

case CMP_BIG:

res = num1 > num2;

break;

default:

res = false;

break;

}

return res;

}

private:

int m_cmpType;

};

void Swap(int &num1, int &num2)

{

int temp = num1;

num1 = num2;

num2 = temp;

}

void SortArray(int array[], int size,const Comparer &cmp)

{

for (int i = 0; i < size - 1; ++i)

{

int indx = i;

for (int j = i + 1; j < size; ++j)

{

if (cmp(array[indx], array[j]))

{

indx = j;

}

}

if (indx != i)

{

Swap(array, array[indx]);

}

}

}

void ListArray(int array[], int size)

{

for (int i = 0; i < size; ++i)

{

cout << array << " ";

}

}

#define ARY_SIZE 10

int main()

{

int array[ARY_SIZE] = {10, 12, 9, 31, 93, 34, 98, 9, 1, 20};

cout << "The initial array is : ";

ListArray(array, ARY_SIZE);

cout << endl;

SortArray(array, ARY_SIZE, Comparer(CMP_BIG));

cout << "The ascending sorted array is :";

ListArray(array, ARY_SIZE);

cout << endl;

SortArray(array, ARY_SIZE, Comparer(CMP_LES));

cout << "The descending sorted array is : ";

ListArray(array, ARY_SIZE);

cout << endl;

return 0;

}

运行结果:

The initial array is : 10 12 9 31 93 34 98 9 1 20

The ascending sorted array is :1 9 9 10 12 20 31 34 93 98

The descending sorted array is : 98 93 34 31 20 12 10 9 9 1

  程序中定义了一个仿函数Comparer,它重重载了()运算符:

  Comparer::bool operator ()(int num1, int num2) const;

  这里温习一下运算符重载的方式:

  ret_type operator opt(array_list);

  其中,ret_type为运算符重载后返回值的类型,operator为c++运算符重载专用关健字,opt为所要重载的运算符,如+, -, *, /, [], ()...

  于是我们可以解读Comparer::bool operator ()(int num1, int num2) const的意义:

  bool限定了()的返回值为布尔类型,(int num1, int num2)指定了运算符()的参数形式,const使得应该运算符可被它的const对象调用。()运算符中根据m_cmpType值返回不同方式下两整数的比较值。

  函数void SortArray(int array[], int size, const Comparer &cmp)用于给数组排序。其中,array[]指定所要排序的数组对象,size限定数组元素个数,cmp为Comparer对象的引用,用作对元素的比较使用,前面使用const修饰是向函数调用都声明,在函数内不会有修改该对象任何数据的形为。注意SortArray中的代码:

if (cmp(array[indx], array[j]))

{

indx = j;

}

  其中,cmp为Comparer类的一个对象,但这里的用法好像它是某个函数的样子。这就是仿函数的真谛。

  别外,void Swap(int &num1, int &num2)完成交换num1与num2值的功能。int &num1表示函数参数使用的引用,用久了c的朋友也许更习惯了void Swap(int *num1, int *num2),但在c++中这个习惯要改了,引用和指针一样高效,但引用要比指针更直观。下面是指针版的Swap函数:

void Swap(int *num1, int *num2)

{

int temp = *num1;

*num1 = *num2;

*num2 = temp;

}

  实现的功能与程序中使用的一模一样,替换掉程序照样正常工作。仔细比较引用版与指针版的Swap()函数,我相信大多数人会爱上C++的引用版。

C++仿函数(functor)详解的更多相关文章

  1. [GeekBand] STL 仿函数入门详解

    本文参考文献::GeekBand课堂内容,授课老师:张文杰 :C++ Primer 11 中文版(第五版) page 37 :网络资料: 叶卡同学的部落格  http://www.leavesite. ...

  2. C++ 谓词(predicate) 与 仿函数 ( functor (function object))

    谓词与函数对象 谓词 predicate C++ 标准定义谓词如下: The Predicate parameter is used whenever an algorithm expects a f ...

  3. for_each的各种情况下的使用详解

    原创作者:http://oomusou.cnblogs.com 配合<C++ Template>(简体中文)使用 http://download.csdn.net/detail/qq239 ...

  4. STL之heap与优先级队列Priority Queue详解

    一.heap heap并不属于STL容器组件,它分为 max heap 和min heap,在缺省情况下,max-heap是优先队列(priority queue)的底层实现机制.而这个实现机制中的m ...

  5. C++中的STL中map用法详解(转)

    原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解   Map是STL的一个关联容器,它提供 ...

  6. Java反序列化漏洞详解

      Java反序列化漏洞从爆出到现在快2个月了,已有白帽子实现了jenkins,weblogic,jboss等的代码执行利用工具.本文对于Java反序列化的漏洞简述后,并对于Java反序列化的Poc进 ...

  7. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  8. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  9. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

随机推荐

  1. 使用Sass优雅并高效的实现CSS中的垂直水平居中(附带Flex布局,CSS3+SASS完美版)

    实现css水平垂直居中的方法有很多,在这里我简单的说下四种比较常用的方法: 1.使用CSS3中的Flex布局 对于flex,我们要了解的是它是一个display的属性,而且必须要给他的父元素设置fle ...

  2. 通过Linux命令过滤出binlog中完整的SQL语句

    DB:5.6.16CentOS:CentOS release 6.3 (Final) 当insert语句通过空格跨行输入的时候,如何提取完整的insert语句! 创建一个空表:mysql> cr ...

  3. php开发过程中用什么方法来加快页面的加载速度

    1,数据库优化;2,php缓存;3,使用zend引擎(其它框架);4,分布式部署;5,静态

  4. 仿知乎/途家导航栏渐变文字动画效果-b

    demo.gif 效果图如上,简单分析下 1.导航栏一开始是隐藏的,随着scrollView滚动而渐变 2.导航栏左右两边的navigationItem是一直显示的 3.导航栏参考了途家app,使用了 ...

  5. c++ g++3.4.5 g++4.8.2 由编译器引起的编译异常

    #include <memory> #include <string> #include <iostream> class Student { public: St ...

  6. 混乱的url编码||URL编码解码问题

    转载自:http://www.ruanyifeng.com/blog/2010/02/url_encoding.html 一.问题的由来. url就是网址,只要上网就一定会用到. 一般来说,URL只能 ...

  7. PE文件结构详解(四)PE导入表

    PE文件结构详解(二)可执行文件头的最后展示了一个数组,PE文件结构详解(三)PE导出表中解释了其中第一项的格式,本篇文章来揭示这个数组中的第二项:IMAGE_DIRECTORY_ENTRY_IMPO ...

  8. lua语言入门之Sublime Text设置lua的Build System

    转自: http://blog.csdn.net/wangbin_jxust/article/details/8911956 最近开始学习LUA语言,使用Sublime Text作为编辑器,不得不说, ...

  9. 天灵灵,地灵灵,但愿这个一定灵!!!python调用win32api,启动应用程序窗口

    这个是逼到没办法,C#那一套,一点基本没有. 还好,网上找到例程,可以指定帐户启动进程,但愿可以摆脱WIN SERVICE启动产生的SESSION 0 隔离问题. 因为这个问题,以SERVICE启动的 ...

  10. 为什么Android 3.0如此罕见?

    3.0(2011年2月)代号蜂巢,专用于android系统的平板电脑,不用于手机.4.0(2011年5月公布)的开发就是让平板电脑和手机能够共用一个版本的系统.4.0通用于平板电脑和手机.