函数对象

c++中函数名后的()称为函数调用运算符。函数调用运算符也可以重载,如果某个类重载了函数调用运算符,则该类的实例就是一个函数对象。函数对象本身并不是很有用,但他们使得算法操作的参数化策略成为可能,使通用性算法变得更加通用(让函数作为参数还可以通过函数指针)

实例

class Add
{
 public:
 double operator()(double x,double y)
 {
   return x+y;
 }
};

Add plus;   //plus就是一个函数对象
cout<<plus(1.2,3.4)<<endl;//通过函数对象调用重载函数
cout<<Add()(1.2,3.4)<<endl; //Add()会创建一个临时对象

学习代码

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
/*
class absInt {

};
*/ //class和struct都是定义类,struct成员默认属性为public

void print(double i)
{
    cout << i << " ";
}

void myforeach(vector<double>::iterator & t1, vector<double>::iterator & t2, void(*fun)(double i))//可以通过函数指针将一个函数作为另一个函数的参数
{
    while (t1 != t2)
    {
        fun(*t1);
        ++t1;
    }
}

struct absInt {
    //重载操作符()
    int operator()(int val)
    {
        return val < 0 ? -val : val;
    }
};
template <typename elementType>
void FuncDisplayElement(const elementType & element)
{
    cout << element << " " ;
}

template <typename elementType>
struct DisplayElement {
    //存储状态
    int m_nCount;
    DisplayElement()
    {
        m_nCount = 0;
    }
    void operator()(const elementType & element)
    {
        ++m_nCount;
        cout << element << " ";
    }
};
int main()
{
    absInt absObj;//函数对象
    int i = -2;
    unsigned int ui = absObj(i);//通过函数对象调用函数
    cout << ui << endl;

    vector<int> a;
    for (int i = 0; i < 10; i++)
    {
        a.push_back(i);
    }

    DisplayElement<int> mResult;
    mResult = for_each(a.begin(), a.end(), mResult);//把函数对象作为参数传递给另一个函数
    cout << endl;
    cout << "数量" << mResult.m_nCount << endl;

    list<char> b;
    for (char c = 'a'; c < 'k'; ++c)
    {
        b.push_back(c);
    }

    for_each(b.begin(), b.end(), DisplayElement<char>());//DisplayElement<char>()会创建一个临时对象
    cout << endl;

    vector<double> vec = { 76,92,86,74,95 };
    cout << "vec里的类容为:" << endl;
    for_each(vec.begin(), vec.end(), print);
    cout << "vec里的内容为" << endl;
    myforeach(vec.begin(), vec.end(), print);

    getchar();
    return 0;
}
  • 构造函数在初始化时调用,即使有函数调用运算符()的重载,并且参数类型一样,只会调用构造函数,函数对象只能声明后,才能调用
  • 例子

    #include <iostream>
    #include <string>
    using namespace std;
    struct student {
        string sno;
        student()
        {
            cout << "调用构造函数son为:" << sno << "#"<<endl;
        }
        student(string sno)
        {
            this->sno = sno;
            cout << "调用构造函数sno为:" << this->sno << "#" << endl;
        }
    
        void operator()(string sno)
        {
            this->sno = sno;
            cout << "调用函数对象sno为:" << this->sno << "#" << endl;
        }
    };
    int main()
    {
        student s("2014");//输出"调用构造函数sno为:2014#"
        student  s2;     //输出"调用构造函数sno为:#"
        s("2014");      //输出"调用函数对象sno为:2014#"
        getchar();
        return 0;
    }

    C++ 函数对象的更多相关文章

    1. 函数对象(仿函数 functor)

      简单地说,函数对象就是一个重载了()运算符的类实例,它可以像一个函数一样使用. #include <iostream> using namespace std; class Add { p ...

    2. javascript 利用匿名函数对象给你异步回调方法传参数

      先来创建一个匿名函数对象: /*** * 匿名函数 */ var callChangeBtn=new function(bugBtn){ this.chage=function(json){ bugB ...

    3. 3.2 STL中的函数对象类模板

      *: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...

    4. C++模板中的函数对象

      在C++模板类map中一个参数为Compare类型,该类型为一个比较函数,其完整定义如下: template< class Key, class T, class Compare = std:: ...

    5. C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象

      函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...

    6. EffectiveJava——用函数对象表示策略

      有些语言支持函数指针.代理.lambda表达式,或者支持类似的机制,允许程序把“调用特殊函数的能力”储存起来并传递这种能力.这种机制通常用于允许函数的调用者通过传入第二个函数,来指定自己的行为.比较器 ...

    7. python 学习笔记3(循环方式;list初始化;循环对象/生成器/表推导;函数对象;异常处理)

      ### Python的强大很大一部分原因在于,它提供有很多已经写好的,可以现成用的对象 16. 循环方式笔记: 1)range(0, 8, 2)   #(上限,下限,步长)  可以实现对元素或者下标的 ...

    8. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

      js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

    9. 认识js函数对象(Function Object)

      认识函数对象(Function Object) 可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函 数名来进行调用.这些都是代码给用户的印象,而在JavaScript ...

    10. Python进阶07 函数对象

      作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函数也是一个对象 ...

    随机推荐

    1. github和本地仓库关联

      1.安装git 2.在github上注册账号 3.github上创建repository 4.克隆github上的repository 5.在target directory中右键打开git gui

    2. Xilinx ISE 14.1中模拟True Dual Port RAM例子

      <一>创建工程 创建工程在此略过. <二>基本代码 1.创建一个Verilog modual代码如下: module main( input clk, input rsta, ...

    3. 数位DP按位枚举模板

      借鉴:http://www.cnblogs.com/xz816111/p/4809913.html // pos = 当前处理的位置(一般从高位到低位) // pre = 上一个位的数字(更高的那一位 ...

    4. 前端的UI设计与交互之色彩篇

      一.颜色Red热情.警示 Green成功.通过.安全 Blue专业.科技 Pink典雅.明快.女性 Orange醒目.温暖 Purple高雅.浪漫 Yellow活力.提示 Cyan清新.冷静.结构化 ...

    5. AngularJS学习篇(二十一)

      AngularJS 动画 AngularJS 提供了动画效果,可以配合 CSS 使用. AngularJS 使用动画需要引入 angular-animate.min.js 库. <!doctyp ...

    6. js中编码问题escape、encodeURI

      未分类 1.js对文字进行编码涉及3个函数:   escape,encodeURI,encodeURIComponent, 相应3个解码函数:unescape,decodeURI,decodeURIC ...

    7. jQuery选择器(内容过滤选择器)第四节

      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

    8. 通过正则表达式提取excel特定列中含有关键字的所有行数据

      在 Excel 中打开需要提取数据excel文件,使用 Alt+F11 快捷键打开 VBA 项目窗口,在左侧的工作表名称上点右键,选择查看代码,即可出现右侧的编辑代码窗口(如下图) 在代码窗口中输入以 ...

    9. python+selenium安装

      1.下载Python 请到官网自行下载安装https://www.python.org/downloads/ 在安装的时候,注意一定要勾上这个选项,可以免去我们配置系统变量的麻烦,如果你忘了,没关系, ...

    10. 《Linux命令行与shell脚本编程大全》 第七章理解Linux文件权限

      Linux沿用了Unix文件权限的方法,允许用户和组根据每个文件和目录的安全性设置来访问文件. 用户权限通过创建用户时分配的用户ID(UID)来跟踪的.每个用户有唯一的ID,但是登录时用的不是UID, ...