原文转自 https://www.cnblogs.com/lvchaoshun/p/7806248.html (修改、增加部分内容)
一 函数指针介绍
函数指针指向某种特定类型,函数的类型由其参数及返回类型共同决定,与函数名无关。举例如下:
1
| int add(int nLeft,int nRight);
|
该函数类型为int(int,int),要想声明一个指向该类函数的指针,只需用指针替换函数名即可:
则pf
可指向int(int,int)
类型的函数。pf
前面有*
,说明pf
是指针,右侧是形参列表,表示pf
指向的是函数,左侧为int
,说明pf
指向的函数返回值为int
。则pf
可指向int(int,int)
类型的函数。而add类型为int(int,int)
,则pf
可指向add函数。
*注意:pf两端的括号必不可少,否则若为如下定义:**
二 标准C函数指针
1 函数指针的定义
1.1 普通函数指针定义
1.2 使用typedef定义函数指针类型
1 2 3
| typedef int (*PF)(int,int);
PF pf;
|
2 函数指针的普通使用
1 2 3
| pf = add; pf(100,100); (*pf)(100,100);
|
注意:add类型必须与pf可指向的函数类型完全匹配
3 函数指针作为形参
1 2 3 4 5 6
| Void fuc(int nValue,int pf(int,int));
Void fuc(int nValue,int (*pf)(int,int)); Void fuc(int nValue,PF);
|
形参中有函数指针的函数调用,以fuc为例:
1 2 3
| pf = add; fuc(1,add); fuc(1,pf);
|
4 返回指向函数的指针
4.1 使用typedef定义的函数指针类型作为返回参数
4.2 直接定义函数指针作为返回参数
1
| int (*fuc2(int))(int,int);
|
说明:按照有内向外的顺序阅读此声明语句。fuc2有形参列表,则fuc2是一个函数,其形参为fuc2(int),fuc2前面有,所以fuc2返回一个指针,指针本身也包含形参列表(int,int),因此指针指向函数,该函数的返回值为int.*
总结:fuc2是一个函数,形参为(int),返回一个指向int(int,int)的函数指针。
三 C++函数指针
1 由于C++完全兼容C,则C中可用的函数指针用法皆可用于C++
2 C++其他函数(指针)定义方式及使用
2.1 typedef与decltype组合定义函数类型
1
| typedef decltype(add) add2;
|
decltype返回函数类型,add2是与add相同类型的函数,不同的是add2是类型,而非具体函数。
2.2 typedef与decltype组合定义函数指针类型
1 2
| typedef decltype(add)* PF2; PF2 pf;
|
2.3 使用推断类型关键字auto定义函数类型和函数指针
1 2
| auto pf = add; auto *pf = add;
|
3 函数指针形参
1 2 3 4
| 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关键字
1
| decltype(add)* fuc2(int)
|
5 成员函数指针
5.1普通成员函数指针使用举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class A//定义类A { private: int add(int nLeft, int nRight) { return (nLeft + nRight); } public: void fuc() { printf("Hello world\n"); } }; typedef void(A::*PF1)();
PF1 pf1 = &A::fuc; A a; (a.*pf1)();
|
5.2继承中的函数指针使用举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| class A { public: void fuc() { printf("Hello fuc()\n"); } void fuc2() { printf("Hello A::fuc2()\n"); } }; class B:public A { public: void fuc2() { printf("Hello B::fuc2()\n"); } }; typedef void(A::*PF1)(); typedef void(B::*PF2)();
PF1 pf1 = &A::fuc; int main() { A a; B b; (a.*pf1)(); (b.*pf1)();
pf1 = &A::fuc2; (a.*pf1)(); (b.*pf1)();
PF2 pf2 = &A::fuc2; (b.*pf2)();
PF2 pf3 = &B::fuc2; (b.*pf3)(); }
|
6 重载函数的指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class A { public: void fuc() { printf("Hello fuc()\n"); } void fuc(int a) { printf("Hello A::fuc(int)\n"); } }; typedef void(A::*PF1)(); typedef void(A::*PF2)(int); PF1 pf1 = &A::fuc; PF2 pf2 = &A::fuc; int main() { A a; (a.*pf1)(); (a.*pf2)(0); return 0; }
|