函数对象,即一个重载了括号操作符“()”的对象。当用该对象调用此操作符时,其表现形式如同普通函数调用一般,因此取名叫函数对象。举个最简单的例子:
class FuncObjType
{
public:
void operator() ()
{
cout<<"Hello C++!"<<endl;
}
};
调用:
FuncObjType func;
func(); //调用的参数设置与operator()()的第二个括号参数保持一致
上述例子运行结果如下:
再看一个稍长一点的简单的函数对象调用实例
函数调用也可以像普通函数一样传参,这个不难看出,这个例子中多了一个函数对象调用时候的传参(“hello”)。
另外,函数对象还有一个函数指针无法匹敌的用法:可以用来封装类成员函数指针!
因为函数对象可以携带附加数据,而成员函数指针缺少一个类实体(类实例)指针来调用,因此,可以把类实体指针给函数对象保存起来,就可以用于调用对应类实体成员函数了,看如下实例:
#include <iostream>
using namespace std;
class A {
public:
void print(const char* name) //一个类中的函数,我们要通过函数对象将其封装
{
cout << "hello " << name << "!" << endl;
}
};
template<typename T>
class funObject {//函数对象
public:
funObject(void(T::* f)(const char*), T* obj) : pFunc(f), pObj(obj) {}//构造函数,传递附加数据
void operator()(const char* name)//通过此函数封装某一个类的函数
{
(pObj->*pFunc)(name);//调用某一个类的一个对象的一个函数成员,这就是封装
}
private:
void(T::* pFunc)(const char*);//储存某一个类中的函数
T* pObj;//储存某一个类的一个对象
};
int main()
{
A a;
funObject<A> call(&A::print, &a);//定义一个函数对象类的对象,传递一个类的对象和一个类的某个成员函数进去
call("kitty");//调用封装对象某个对象的()函数,在此函数中,我们又进而通过某一个类的一个对象调用此类的一个成员函数
return 0;
}
运行结果如下:
代码定义了一个函数对象call,传递的数据与funObject的构造函数保持一致,通过对函数对象的调用,实现封装类成员函数指针(T* pObj)