调用操作符的重载与函数对象
一:调用操作符重载:我们可以为类类型的对象重载调用操作符即小括弧”()“,定义了调用操作符的类,在使用定义的调用操作符时,行为就像是调用函数,所以这种对象称为函数对象,即行为类似函数的对象:
如下例子为类A定义了调用操作符,功能是返回一个绝对值:
class A
{
public:
int operator() (int val)
{
return val < 0 ? -val : val;
}
};
调用操作符使用以下两种方法都可以:
A a;
int n = a.operator()(-1);
int n = a(-1); //使用方式像是调用了一个函数
调用操作符可以重载多个版本,通过函数形参的类型及数目区分,如再为类A重载一个形参类型为char *的调用操作符函数:
void operator(char *p)
{
*p = '\0';
}
使用以上调用操作符:
char arr[] = "ABC";
char *pa = arr;
a.operator()(pa);
a(pa);
二:函数对象用于标准库算法:
a:例如查找比指定值大的数,可以先定义一个类B,为其定义调用操作符,使用该类的对象实现查找:
class B
{
public:
B(int val = 0) : ival(val) {} //构造函数初始化成员 ival;
bool operator()(const int &v)
{
return v > ival; //返回真值,如果传递进来的实参大于成员ival,ival在调用构造函数时被初始化;
}
private:
int ival;
};
用标准库算法find_if进行查找,比如查找大于10的数:
int b[] = {1, 52, 12, 30, 9, 19};
vector<int> ivec(b, b+6);
vector<int>::iterator ite = ivec.begin();
while((ite = find_if(ite, ivec.end(), B(10))) != ivec.end())
{
cout << *ite << " ";
ite++;
}
find_if函数的第三个参数是一个接受一个参数并返回bool型的函数,在这里我们可以传递给find_if算法函数一个类类型B的临时对象,通过传递值10给构造函数初始成员ival,现在find_if每次调用它的函数形参时,依次将vector中的每个元素都应用类B的调用操作符,然后该操作符根据成员ival的值,对传进的实参即vector的每个元素进行比较,如果函数对象返回为真,则find_if返回指向该元素的迭代器;
b:统计大于指定值的次数,以上述代码为基础:
int n = count_if(ivec.begin(), ivec.end(), B(10));
同样,count_if以函数调用的方式调用类B调用操作符,对vector中每个元素进行比较,如果为真,则计数器加1,知道vector的末端元素;
全部代码:
- #include <iostream>
- #include <vector>
- #include <algorithm>
- using namespace std;
- class A
- {
- public:
- int operator() (int val)
- {
- return val > 0 ? val : -val;
- }
- void operator() (char *p)
- {
- *p = 'B';
- }
- };
- class B
- {
- public:
- B(int val = 0) : ival(val) {} //构造函数初始化成员 ival;
- bool operator()(const int &v)
- {
- return v > ival; //返回真值,如果传递进来的实参大于成员ival,ival在调用构造函数时被初始化;
- }
- private:
- int ival;
- };
- int main()
- {
- int i = -42;
- A a;
- unsigned int ui = a(i);
- // unsigned int ui = a.operator()(i);
- cout << ui << endl;
- char arr[] = "ABC";
- char *pa = arr;
- a(pa);
- //a.operator()(pa);
- cout << pa << endl;
- int b[] = {1, 52, 12, 30, 9, 19};
- vector<int> ivec(b, b+6);
- vector<int>::iterator ite = ivec.begin();
- while((ite = find_if(ite, ivec.end(), B(10))) != ivec.end())
- {
- cout << *ite << " ";
- ite++;
- }
- cout << endl;
- int n = count_if(ivec.begin(), ivec.end(), B(10));
- cout << "n:" << n << endl;
- return 0;
- }
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class A
{
public:
int operator() (int val)
{
return val > 0 ? val : -val;
}
void operator() (char *p)
{
*p = 'B';
}
};
class B
{
public:
B(int val = 0) : ival(val) {} //构造函数初始化成员 ival;
bool operator()(const int &v)
{
return v > ival; //返回真值,如果传递进来的实参大于成员ival,ival在调用构造函数时被初始化;
}
private:
int ival;
};
int main()
{
int i = -42;
A a;
unsigned int ui = a(i);
// unsigned int ui = a.operator()(i);
cout << ui << endl;
char arr[] = "ABC";
char *pa = arr;
a(pa);
//a.operator()(pa);
cout << pa << endl;
int b[] = {1, 52, 12, 30, 9, 19};
vector<int> ivec(b, b+6);
vector<int>::iterator ite = ivec.begin();
while((ite = find_if(ite, ivec.end(), B(10))) != ivec.end())
{
cout << *ite << " ";
ite++;
}
cout << endl;
int n = count_if(ivec.begin(), ivec.end(), B(10));
cout << "n:" << n << endl;
return 0;
}
运行结果:
42
BBC
52 12 30 19
n:4
上述代码gcc编译通过!