C/C++普通函数指针和类成员函数指针的使用

之前一直以为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 = 3
0x10162ded0 0x10162ded0  // 输出的四个地址都是一样的
0x10162ded0 0x10162ded0 

关于 typedef 函数指针类型

可以对照普通用法看一看

// 直接声明变量
int i = 1;
void (*sum)(int, int) = printSum;

// 使用typedef
typedef 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 = 3
0x10300ef40

typedef 成员函数指针类型

typedef void (Sample::*SUM)(int, int);
SUM sum = &Sample::printSum;

总结

还是以上面的代码函数的定义为例:

  • 普通成员函数的类型为void (*)(int, int),类成员函数类型为void (Sample::*)(int, int),后者一定要加类名
  • 函数指针的定义和普通函数类似,区别是普通函数的变量名写在类型后面,函数指针类型变量名写在类型中间
  • 普通函数的函数名可以作为函数入口指针,加不加&符号都一样效果,类成员函数的指针必须加&符号,调用的时候也必须加*。 可以理解为普通函数名字等同于地址,成员函数的名字和地址不是一个东西。

代码在Mac gcc测试通过,有问题欢迎交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章