[C++] 函数指针

1.函数指针的定义

int (*fp)(int a,int b);

这里fp就是一个函数指针,表面上看,它的语法即是把函数名替换成指针,再加个括号。

#include<iostream>
using namespace std;
void show(int num){
	cout<<num;
}
int main(){
	void (*fp) (int a);//括号一定要加,否则报错 error: cannot convert 'void(int)' to 'void*(int)' in assignment
        typedef void(*fp1)(int a);//这里可以使用typedef定义一个类型(type),这里是一个返回值为void型函数指针的名叫fp1的函数指针类型
        fp1 fp_1 = show;//接着就可以定义某个具体的函数指针“变量”,这个变量的指针指向show这个函数
	fp = show;//fp同样指向show这个函数
	fp(5);
        fp_1(5);
        

        fp_2[3]={show,show,show};
        fp_2[0](3);//同样,还可以创建数组。
	return 0;
}

这里有两个括号,第一个括号是指定函数指针的名字,第二个括号里是这个函数的参数。

2.函数指针的使用

看到网上说,处于历史原因,有以下两种方法,他们都可以都是通过函数指针调用相关函数的方法。

(*fp)(2);
fp(2);

另外,函数指针还可以作为参数传递,作为参数传递给另一个函数的这个函数,就是所谓的回调函数,因为这个函数在这里的存在就是为了回调来获得它的值。



#include<iostream>
using namespace std;

int show(int num){
	cout<<num;
        return num;
}

int show2(int(*fun)(int),int b)
{
     cout<<fun(b)+b;
     return b;
}

int main(){
	int(*fp) (int a);//括号一定要加,否则报错 error: cannot convert 'void(int)' to 'void*(int)' in assignment
        typedef int(*fp1)(int a);//这里可以使用typedef定义一个类型(type),这里是一个返回值为void型函数指针的名叫fp1的函数指针类型
        fp1 fp_1 = show;//接着就可以定义某个具体的函数指针“变量”,这个变量的指针指向show这个函数
	fp = show;//fp同样指向show这个函数
	fp(5);
        fp_1(5);
        show2(fp,2);
       // show2(fp(3),2);注意fp(3)的返回值是int型,所以这不能这样写

        fp_2[3]={show,show,show};
        fp_2[0](3);//同样,还可以创建数组。

        
	return 0;
}

3.函数指针在类里的使用

因为在类中使用函数指针和其它情况略有不同,为了不致混淆,单独把它的定义和使用都列在第三点中。

首先一个指针通过类的函数赋值,需要加上&符号。

void (A::*pa)(int) = &A::func1;//这里void 和func1的返回值类型(要)相同
//注意*号的位置,不是void (*A::pa)(int) = &A::func1;(不过这样可不可以我还没试)

其次我们知道类中可以有一下几类函数:构造函数、析构函数、拷贝构造函数、赋值函数、虚函数、友元函数、静态成员函数、非静态成员函数(也就是普通的成员函数)。

这里没有完全按照一种标准分类,原因是我觉得函数存在能不能被赋值给函数指针(或者可以赋值但是赋值会有什么风险)和赋值方式是否相同的问题。下面来说下这两个问题:
首先只有静态成员函数能赋值给静态成员函数指针,同样,只有非静态成员函数能赋值给非静态成员函数指针。有点绕,但关系是简单的。
其次在非静态成员函数中,虚函数是没有实际地址的,所以其地址实际上是在虚表中的相对地址。
还有一个在其他示例中几乎看不到的用法,那就是解引用(dereference)的用法

A a;
(a.*a.pa)();
/*这里意思实际上是a.func1(),不妨把它当做一个数学公式,那就是pa = &func1,这里pa是一个指针,同时还是A类的成员函数
又有 *(&func1)=func1,所以*a.pa = func1

4.typedef+static 数组变量+函数模板+函数

最后说的这个,差不多是我见过最复杂的情形了,形如

typedef void (*Func)(int a,int b,int c);
template<class A,class B,typename T>
static void foo(int a,int b,int c)
{

    /*blah blah*/

}

static Func func_tab[] = 
{
   foo<cA0,cB0,tT0>,
   foo<cA1,cB1,tT1>,
   //...
   foo<cAn,cBn,tTn>,
} 

posted @ 2018-08-03 17:37  zengzhaocheng  阅读(144)  评论(0编辑  收藏  举报