之前一直以为C++成员函数没法取地址,一直使用静态函数来充当回调函数,直到近日看别人的代码才发现类成员函数也有指针。。。总结记录一下。
普通函数指针
这面是普通函数的指针的使用方法。
#include <stdio.h>void printSum(int a, int b) {printf("%d + %d = %d\n", a, b, a+b);}int main() {// 声明一个函数指针变量,和声明一个普通变量类似,只是需要把这个变量名字放在这一串字符中间而已。void (*sum)(int, int); sum = &printSum; // 带不带&符号都一样效果,函数名也表示地址。// sum = printSum; // 也可以这样sum(1, 2);printf("%p %p \n", printSum, &printSum); // 打印出来的地址是一样的,所以上面加不加&符号效果都一样printf("%p %p \n", sum, *sum);return 0;}
输出
1 + 2 = 30x10162ded0 0x10162ded0 // 输出的四个地址都是一样的0x10162ded0 0x10162ded0
关于 typedef 函数指针类型
可以对照普通用法看一看
// 直接声明变量int i = 1;void (*sum)(int, int) = printSum;// 使用typedeftypedef int INT;INT a = 1;typedef void (*SUM)(int, int);SUM fun = printSum;
类成员函数指针
与普通成员函数指针相比,类成员函数指针必须加上类名::
。
#include <stdio.h>class Sample {public:void printSum(int a, int b){printf("%d + %d = %d\n", a, b, a+b);}};int main() {void (Sample::*sum)(int, int);sum = &Sample::printSum; // 这个必须加&,与普通函数不同Sample *ins = new Sample;(ins->*sum)(1, 2); // 注意:这里需要加星*printf("%p", &Sample::printSum);return 0;}
输出
1 + 2 = 30x10300ef40
typedef 成员函数指针类型
typedef void (Sample::*SUM)(int, int);SUM sum = &Sample::printSum;
总结
还是以上面的代码函数的定义为例:
普通成员函数的类型为void (*)(int, int)
,类成员函数类型为void (Sample::*)(int, int)
,后者一定要加类名。函数指针的定义和普通函数类似,区别是普通函数的变量名写在类型后面,函数指针类型变量名写在类型中间。普通函数的函数名可以作为函数入口指针,加不加&
符号都一样效果,类成员函数的指针必须加&
符号,调用的时候也必须加*
。 可以理解为普通函数名字等同于地址,成员函数的名字和地址不是一个东西。
代码在Mac gcc测试通过,有问题欢迎交流。