一、概念
仿函数又称为函数对象是一个能行使函数功能的类,仿函数是定义了一个含有operator()成员函数的对象,可以视为一个一般的函数,只不过这个函数功能是在一个类中的运算符operator()中实现,是一个函数对象,它将函数作为参数传递的方式来使用。
写一个简单类,除了维护类的基本成员函数外,只需要重载 operator() 运算符 。这样既可以免去对一些公共变量的维护,也可以使重复使用的代码独立出来,以便下次复用。
二、应用领域
1 表面像函数,部分场景中可以代替函数,在STL中得到广泛的应用
2 函数对象本质是类,可以用成员变量存放更多的信息;
3 函数对象有自己的数据类型;
4 可以提供继承体系。
三、代码演示
这是调用普通的函数
#include <iostream>
using namespace std;
void show() {
cout << "我是普通函数" << endl;
}
int main() {
show();
return 0;
}
仿函数(函数对象)就是对()运算符进行重载,而且重载只能在类中用成员函数的方式重载,重载完之后类对象就可以像函数一样使用,代码如下:
#include <iostream>
using namespace std;
void show(){
cout << "我是普通函数" << endl;
}
class A{
public:
void operator()(const string str) {
cout << "我是重载()的函数,也叫仿函数 " << str << endl;
}
};
int main() {
A func;
func("hello world");
show();
return 0;
}
运行结果:
我们来考虑一下作用域的问题,如果类对象和全局函数名称一样,咋办呢?答案是,按作用域规则调用所需要的函数,具体看代码演示:
int main() {
show();//此时类成员show未定义,所以调用的是全局函数show
A show;//此时show已经定义,所以调用的是重载()的类成员函数
show("hello world");
return 0;
}
执行结果
如果代码是这样:
int main() {
A show;//此时show已经定义,所以调用的是重载()的类成员函数
show("hello world");
show("!!!");//此时show已经定义,所以调用的是重载()的类成员函数
::show();//如果想要访问全局函数,只需要在前面加上两个冒号
return 0;
}
执行结果
四、总结
- 括号运算符()也可以重载,对象名可以当成函数来使用(函数对象、仿函数)括号运算符重载函数的语法:返回值类型 operator()(参数列表);
- 括号运算符必须以成员函数的形式进行重载。
- 括号运算符重载函数具备普通函数全部的特征。
- 如果函数对象与全局函数同名,按作用域规则选择调用的函数。