指向函数的指针变量。
每个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数。
用途:
调用函数和做函数的参数,比如回调函数。
示例:
1 char * fun(char * p) {…} // 函数fun 2 3 char * (*pf)(char * p); // 函数指针pf 4 5 pf = fun; // 函数指针pf指向函数fun 6 7 pf(p); // 通过函数指针pf调用函数fun
一、函数指针
指向某种特定的类型,这个类型由函数返回的类型决定。
int add(int nLeft,int nRight);//函数定义
这个函数类型是int(int,int),声明一个指向这类函数的指针:
int (*pf)(int,int);//未初始化
pf可指向int(int,int)类型的函数。
给函数指针赋值:
pf = add;//通过赋值使得函数指针指向某具体函数
二、c中函数指针
1、定义
//方法二 int (*pf)(int,int); //方法二 typedef int (*PF)(int,int); PF pf;//此时,为指向某种类型函数的函数指针类型,而不是具体指针,用它可定义具体指针
2、使用
pf = add; pf(100,100);//与其指向的函数用法无异 (*pf)(100,100);//此处*pf两端括号必不可少
add类型必须与pf可指向的函数类型完全匹配
3、函数指针作为形参
//第二个形参为函数类型,会自动转换为指向此类函数的指针 Void fuc(int nValue,int pf(int,int)); //等价的声明,显示的将形参定义为指向函数的指针 Void fuc(int nValue,int (*pf)(int,int)); Void fuc(int nValue,PF);
形参中有函数指针的函数调用,以fuc为例:
pf = add;//pf是函数指针 fuc(1,add);//add自动转换为函数指针 fuc(1,pf);
4、返回指向函数的指针
使用typedef定义的函数指针类型作为返回参数:
PF fuc2(int);//PF为函数指针类型
直接定义函数指针作为返回参数
int (*fuc2(int))(int,int);//显示定义
按照有内向外的顺序阅读此声明语句。fuc2有形参列表,则fuc2是一个函数,其形参为fuc2(int),fuc2前面有*,所以fuc2返回一个指针,指针本身也包含形参列表(int,int),因此指针指向函数,该函数的返回值为int.
总结:fuc2是一个函数,形参为(int),返回一个指向int(int,int)的函数指针。
三、c++中定义函数指针
C++完全兼容C,则C中可用的函数指针用法皆可用于C++。
1、定义函数类型
typedef与decltype组合定义函数类型:
typedef decltype(add) add2;
decltype返回函数类型,add2是与add相同类型的函数,不同的是add2是类型,而非具体函数。
add2* pf;//pf指向add类型的函数指针,未初始化
2、定义函数指针类型
typedef decltype(add)* PF2;//PF2与1.1PF意义相同 PF2 pf;// pf指向int(int,int)类型的函数指针,未初始化
2.3 使用推断类型关键字auto定义函数类型和函数指针
- auto pf = add;//pf可认为是add的别名(个人理解)
- auto *pf = add;//pf为指向add的指针
3函数指针形参
- typedef decltype(add) add2;
- typedef decltype(add)* PF2;
- void fuc2 (add2 add);//函数类型形参,调用自动转换为函数指针
- void fuc2 (PF2 add);//函数指针类型形参,传入对应函数(指针)即可
说明:不论形参声明的是函数类型:void fuc2 (add2 add);还是函数指针类型void fuc2 (PF2 add);都可作为函数指针形参声明,在参数传入时,若传入函数名,则将其自动转换为函数指针。
4 返回指向函数的指针
4.1 使用auto关键字
1
|
auto fuc2( int )-> int (*)( int , int ) //fuc2返回函数指针为int(*)(int,int) |
4.2 使用decltype关键字
- decltype(add)* fuc2(int)//明确知道返回哪个函数,可用decltype关键字推断其函数类型,
5 成员函数指针
5.1普通成员函数指针使用举例
- class A//定义类A
- {
- private:
- int add(int nLeft, int nRight)
- {
- return (nLeft + nRight);
- }
- public:
- void fuc()
- {
- printf("Hello world ");
- }
- };
- typedef void(A::*PF1)();//指针名前需加上类名限定
- PF1 pf1 = &A::fuc; //必须有&
- A a;//成员函数地址解引用必须附驻与某个对象地址,所以必须创建一个队形
- (a.*pf1)();//使用成员函数指针调用函数
5.2继承中的函数指针使用举例
- class A
- {
- public:
- void fuc()
- {
- printf("Hello fuc() ");
- }
- void fuc2()
- {
- printf("Hello A::fuc2() ");
- }
- };
- class B:public A
- {
- public:
- virtual void fuc2()
- {
- printf("Hello B::fuc2() ");
- }
- };
- typedef void(A::*PF1)();
- typedef void(B::*PF2)();
- PF1 pf1 = &A::fuc;
- int main()
- {
- A a;
- B b;
- (a.*pf1)(); //调用A::fuc
- (b.*pf1)(); //调用A::fuc
- pf1 = &A::fuc2;
- (a.*pf1)(); //调用A::fuc2
- (b.*pf1)(); //调用A::fuc2
- PF2 pf2 = &A::fuc2;
- (b.*pf2)(); //调用A::fuc2
- }
6重载函数的指针
6.1 重载函数fuc
- Void fuc();
- Void fuc(int);
6.2 重载函数的函数指针
- void (*PF)(int) = fuc;//PF指向fuc(int)
- int(*pf2)(int) = fuc;//错误没有匹配的类型
注意:编译器通过指针类型决定选取那个函数,指针类型必须与重载函数中的一个精确匹配。