重载了“( )”运算符的自定义类型生成的对象可以像函数名一样调用该类的“( )”运算符函数,所以该对象称为函数对象。函数对象一般被用于代替函数指针。函数指针作为另外一个函数的参数,可以使该函数更具通用性,使程序更具可扩展性,通过程序1(使用函数指针)和程序2(使用函数对象)的比较,来说明函数对象相对于函数指针的优势.
1、//使用函数指针的情况:
2 #include<iostream>
3 using std::cout;
4 using std::endl;
5
6 void print_if(const int * arr,int len,bool (*con)(int))
7 {
8 for(inti=0;i<len;++i)
9 if(con(arr[i]))
10 cout<<arr[i]<<" ";
11 cout<<endl;
12 }
13 bool less_5(int n)
14 {
15 return n<5;
16 }
17 bool greater_10(int n)
18 {
19 return n>10;
20 }
21 bool not_equal_0(int n)
22 {
23 return n!=0;
24 }
25 int main()
26 {
27 int a[10]={0,1,2,35,46,4,8,0,6,0};
28
29 print_if(a,10,less_5);
30 print_if(a,10,greater_10);
31 print_if(a,10,not_equal_0);
32
33 return 0;
34 }
显式结果:
0 1 2 4 0 0
35 46
1 2 35 46 4 8 6
程序1中的函数print_if使用函数指针作为参数,使其有一定的通用性。但是,这种通用性是有限的,例如,如果想要输出数组中小于20、大于30等等满足其它条件的元素时,程序总要为新的条件添加类似于less_20、greater_30的判定函数。这一缺陷使print_if函数不能使用运行时的判定条件进行数组元素的输出(判定函数总是事先写好)。为了解决这一问题,需要一种运行时把信息传递给判定函数的方法.因此我们可以使用函数对象代替函数指针。函数对象可以向全局函数一样执行某种操作,又可以像对象一样通过成员变量内置一些信息。
1//使用函数对象的情况
2 #include<iostream>
3 using std::cout;
4 using std::endl;
5 enum Relations {equal,not_equal,less,greater,less_equal,greater_equal};//定义的有限集合常量,参看下一文" enum类型的本质".
6 class FunctionObject
7 {
8 intvalue;
9 Relationsrel;
10 public:
11 FunctionObject(intv,Relations r):value(v),rel(r)
12 {}
13 bool operator()(int n)
14 {
15 switch(rel)
16 {
17 caseequal:return n==value;
18 casenot_equal:return n!=value;
19 caseless:return n<value;
20 casegreater:return n>value;
21 caseless_equal:return n<=value;
22 casegreater_equal:return n>=value;
23 default:return 1;
24 }
25 }
26 };
27 void print_if(const int *arr,int len,FunctionObject con)
28 {
29 for(int i=0;i<len;++i)
30 if(con(arr[i]))
31 cout<<arr[i]<<" ";
32 cout<<endl;
33 }
34
35 int main()
36 {
37 int a[10]={0,1,2,35,46,4,8,0,6,0};
38
39 print_if(a,10,FunctionObject(5,less));
40 print_if(a,10,FunctionObject(10,greater));
41 print_if(a,10,FunctionObject(0,not_equal));
42
43 return 0;
44 }
显式结果:
0 1 2 4 0 0
35 46
1 2 35 46 4 8 6
函数print_if的第3个参数是FunctionObject生成的函数对象,在这3次函数print_if的调用中,我们通过传递不同的无名函数对象,来输出满足不同条件的数组元素。