函数调用是C++中再频繁不过的一项操作了,函数可以直接调用,也可以通过函数指针来调用,也可以通过函数对象来间接调用,形式多样化。下面来看看函数指针和函数对象的区别。
1.函数指针
1)定义
函数指针是指向函数的指针变量。在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址。函数指针主要有两个作用:用作调用函数和做函数的参数。
2)声明方法
数据类型标志符 (指针变量名) (形参列表);
一般函数的声明为: int fun( int x ); 而一个函数指针的声明方法为:int (*fun) (int x);
前面的那个(*fun)中括号是必要的,这会告诉编译器我们声明的是函数指针而不是声明一个具有返回型为指针的函数,后面的形参要视这个函数指针所指向的函数形参而定。
然而这样声明我们有时觉得非常繁琐,于是 typedef 可以派上用场了,我们也可以这样声明:
typedef int (*pf) (int x);
pf p;
这样 p 便是一个函数指针。当要使用函数指针来调用函数时,fun(x)、(*fun)(x) 就可以了,当然,函数指针也可以指向被重载的函数,编译器会为我们区分这些重载的函数从而使函数指针指向正确的函数。
Demo:
typedef void (*P) ( char ,int );
void bar(char ch, int i) {
cout<<"bar "<<ch<<' '<<i<<endl;
return ;
}
P p;
p = bar;
(*p)('e',91); // 或 p('e',91);
例子中函数指针p指向了一个已经声明的函数bar(),然后通过p来调用函数。
函数指针另一个作用便是作为函数的参数,我们可以在一个函数的形参列表中传入一个函数指针,然后便可以在这个函数中使用这个函数指针所指向的函数,这样便可以使程序变得更加清晰和简洁,而且这种用途技巧可以帮助我们解决很多棘手的问题,使用很小的代价就可获得足够大的利益(速度+复杂度)。
Demo:
// 核心内容,非完整程序
typedef void (*P) ( char ,int );
void bar(char ch, int i) {
cout<<"bar "<<ch<<' '<<i<<endl;
return ;
}
void foo(char ch, int i, P p) {
(*p)(ch,i);
return ;
}
int main() {
P p;
p = bar;
foo('e',12,p);
}
上述例子我们首先利用一个函数指针p指向bar(),然后在foo()函数中使用p指针来调用bar(),实现目的。将这个特点稍加利用,我们就可以构造出强大的程序,只需要同样的foo函数便可以实现对不同bar函数的调用。