C++中的 operator() 有两大主要作用:
1:Overloading --------重载() 操作符
2: Casting------实现对象类型转化
1:Overloading重载() 操作符
函数对象(仿函数):定义了调用操作符() 的类对象。当用该对象调用此操作符时,其表现形式如同普通函数调用一般。因此取名叫函数对象,它是一个类,不是一个函数。
class A {
public :
mutable int var; // 定义可变成员变量
int operator() (int val) {
return val >0 ? val : -val
}
}
上面的操作符 operator() 表示的意思就是: 类A 中定义了操作符() ,A对象调用语句在形式上跟以下函数的调用完全一样:
int i = -1 ;
A func;
std::cout << func(i);
那么,operator()函数对象 操作符与普通函数相比,有哪些有点了
- 函数对象比函数更加灵活;
- 函数对象可以有自己的状态,我们可以在类中定义状态变量,这样一个函数对象在多次的调用中可以共享这个状态;但是普通函数就没有这种优势,除非它使用全局变量来保存这个状态。
- 函数对象有自己特有的类型,我们可以传递相应的类型作为参数来实例化相应的模板,比如说带参数的函数形参。而普通函数就无类型可言,这种特性对于使用C++标准库来说是至关重要的,这样我们在使用STL中的函数时,可以传递相应的类型作为参数来实例化相应的模板,从而实现我们自己定义的规则和定制自己的算法。
2:使用函数对象的经典例子
打印小于5的数值。
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
class print {
public:
print(int j) : m_j(j)
{
// 声明静态变量 count_num来统计进入函数的次数
static int count_num = 0;
cout << "进入构造函数次数:" << count_num++ << endl;
}
public:
void operator()(int i)
{
if (i < m_j) {
cout << i << endl;
}
}
public:
int m_j;
};
int main(int argv, char* argc[])
{
vector<int> it = { 1,2,3,4, 6, 7, 8 };
for_each((), (), print(5));
return 0;
}
// 打印结果
进入构造函数次数:0
1
2
3
4
仿函数配合 STL进行使用,用于方便模板类和模板函数,还是上面的例子,但是现在不确定 vector存储的类型,也不确定所输出的条件。
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
/**
类模板
作用:建立一个通用类,类中的成员数据类型可以不具体指定,用一个虚拟的类型来代表。
语法:template<typename T>
解释:template ------声明创建模板
typename ------ 表明后面的符号是一种数据类型,并且可以用class 替代
T ------通用的数据类型,名称开业替换,通常为大写字母
*/
template<typename T>
class print {
public:
print(T j) : m_j(j)
{
// 声明静态变量 count_num来统计进入函数的次数
static int count_num = 0;
cout << "进入构造函数次数:" << count_num++ << endl;
}
public:
// 输出比 i 小的值
void operator()(int i)
{
if (i < m_j) {
cout << i << endl;
}
}
// 打印字符串长度大小小于i 的值
void operator()(string i) {
if (()<m_j)
{
cout << i << endl;
}
}
public:
T m_j;
};
int main(int argv, char* argc[])
{
vector<int> it = { 1,2,3,4, 6, 7, 8 };
// 我们在初始化一个对象,需要显示的指定模板参数列表类型。
for_each((), (), print<int>(5));
vector<string> it2 = { "123", "12345", "123436", "1343253245" };
for_each((), (), print<int>(5));
return 0;
}
// 打印输出
进入构造函数次数:0
1
2
3
4
进入构造函数次数:1
123