函数对象

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;
    }

    最新文章

    1. 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
    2. 使用axi_datamover完成ZYNQ片内PS与PL间的数据传输
    3. 调整Win7中TCP/IP半开连接数限制
    4. ExtJS入门教程04,这是一个超级好用的grid
    5. MemoryStream 的GetBuffer() 和 ToArray()的区别
    6. PE头的应用---插入代码到EXE或DLL文件中
    7. git stash用法
    8. [C++STDlib基础]关于C标准输入输出的操作——C++标准库头文件&lt;cstdio&gt;
    9. 7种创建线程方式,你知道几种?线程系列Thread(一)
    10. Java文件操作(IO流)
    11. 笨鸟先飞之ASP.NET MVC系列之过滤器(03动作过滤器过滤器)
    12. selenium登录163邮箱
    13. 用SpringCloud进行微服务架构演进
    14. Jenkins pipeline:pipeline 语法详解
    15. Python简单实现KNN算法
    16. 2501 矩阵距离 (bfs)
    17. [leetcode]75. Sort Colors三色排序
    18. 关于javaBean,pojo,EJB
    19. JavaScript时间操作工具类
    20. Java static 使用

    热门文章

    1. c++ 类覆盖方法中的协变返回类型
    2. hihocoder 1015题
    3. D - MUH and Cube Walls
    4. 暑假练习赛 003 A Spider Man
    5. Unity 游戏框架搭建 (七) 减少加班利器-QApp类
    6. Problem C: 学生的排序
    7. Jenkins TFS配置
    8. Java面试题技术类
    9. AsciidocFX编辑器小贴士
    10. Windows Forms DataGridView中合并单元格