函数以及函数对象都可以作为参数来增加其它函数的功能,并且通常作为STL算法的第二个版本的最后一个参数。成员函数是否可以作为形参呢?如果可以,形参表如何写呢?
1 函数作为函数形参
首先,成员函数作为C++中一种特殊的函数,是可以作为函数形参的。先来看一下普通函数是如何作为形参的。
void print(int i) { cout << i << " "; } void func(void (*pfunc)(int), int i) { pfunc(i); } int main() { void (*pfun)(int i); pfun = print; func(pfun, 6); return 0; }
上述代码有两个函数print()和func(),然后在主函数中定义了一个函数指针pfun,它的形式和print()一样,因此,可以用print()对pfun进行设置,最后,在func中使用该函数指针进行调用,当然,也可以直接使用print()。
那么,对于成员函数有什么不同呢?
2 使用成员函数指针调用成员函数
下面来看看如何使用成员函数指针调用成员函数,以及和普通的函数有什么不同。
class A { public: void fun(int a) { cout << a; } }; int main() { A a; void (A::*ptrfun)(int); ptrfun = &A::fun; (a.*ptrfun)(2); return 0; }在上述代码中,定义了一个名为A的类,类中有一个名为fun的函数。在主函数中,定义了一个A的对象a,然后定义了成员函数指针ptrfun,它的形式和A中的fun一样,于是,可以用A的fun对ptrfun进行赋值,最后使用ptrfun调用该函数。
这里有几个值得注意的问题:
(1)在对普通函数指针进行赋值时,不用加&:pfun = print,但是,对成员函数指针进行赋值时,必须加&:ptrfun = &A::fun。这涉及到函数类型与函数指针类型,对于普通函数,当定义了一个函数指针,将函数名赋值给函数指针,函数类型会默认转换成函数指针,因此pfun = print或者pfun = &print都是可行的,只是pfun = print中有一层默认的转换。而对于成员函数,当定义了一个成员函数指针ptrfun,如果直接用A::fun进行赋值,编译器会将它理解为A中的静态成员,会产生编译错误,所以,这里的&是必须的。不过,如果写成这样ptrfun
= &(A::fun);也会发生编译错误,因为,将A::fun作为一个整体,编译器就会将fun理解为A中的静态成员,所以,要将&A::fun作为一个整体,即使::的优先级较高。
(2)同样,对于调用方式也有类似的不同。对于普通函数,(*pfun)()和pfun()都是可以的。对于成员函数,只能是(a.*ptrfun)()。
3 将成员函数作为函数形参
总算到了正题。。。
从前述知道,要将成员函数作为函数形参,只要将函数的形参设为成员函数指针,然后在函数体中调用就行。
class A { public: void fun(int a) { cout << a; } }; void test(A x, void (A::*pfun)(int), int y) { (x.*pfun)(y); } int main() { void (A::*ptrfun)(int); ptrfun = &A::fun; A a; test(a, ptrfun, 3); return 0; }
上述代码定义了一个类A以及一个成员函数fun,然后在test中用fun函数类型指针作为参数进行调用,对于非静态函数的调用,必须指定对象,因此,test的第一个参数是一个对象。主函数中的代码和第2小节类似。