☰
C++函数指针的用法详解
2026/9/25 10:08:57 网站建设 项目流程

函数指针初识

函数指针是指向函数的指针,并不等于函数,它能够执行函数的操作,可以跟指针变量一起来理解,其基本声明格式为:

1

type (*ptrname)(形参列表);

例子,声明一个比较两个字符串大小的函数指针

1

bool(*cp)(conststring s1,conststring s2);

需要注意的是,不要去掉括号!!!如果去掉括号,含义就变成了返回一个bool指针的函数的声明!

函数指针指向函数类型

在使用函数指针时,函数指针可以发挥与函数相同的功效,即也可以起到执行任务的作用,但是函数指针需要初始化,而且不存在函数指针类型的转换,在进行初始化的时候,函数指针可以被赋值为nullptr或常量NULL,或者指向一个函数,但是,指向这个函数时,需要有严格的要求,它需要严格按照两者的返回类型,形参列表相对应

例子

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// 两个示例函数

bool compareLength(const string s1, const string s2){

//当s1的长度大于s2的长度,返回true,否则返回false

return s1.size() > s2.size()?true:false;

}

int getLength(const string s1){

//返回字符串的长度

return s1.size();

}

// 初始化前面定义的cp函数指针

cp = nullptr; // 正确,初始化为空

cp = NULL; // 正确,初始化为空常量NULL

cp = compareLength; // 正确,函数的返回形式和形参列表和类型都是一样的

cp = getLength; // 错误,返回类型和形参列表不一样

使用函数

接着上面的思路,函数调用的方式可以这样写

1

2

3

4

5

6

7

8

// 函数指针调用函数

cp(s1, s2);

// 调用2

(*cp)(s1, s2);

// 函数调用,与cp一样

compareLength(s1, s2);

函数指针作为形参使用

可以将函数或者函数指针作为某一个函数的形式参数传入并使用,如C++11的thread头文件线程的构造函数中急需要传递一个函数指针的实例

1

2

3

#include<thread>

std::threadt(函数指针, ..Args);

其声明定义形式如下,比如将上面定义的函数或函数指针传入一个新的函数中,作为两者的比较依据

1

2

3

4

5

6

7

8

9

10

intpackageFunc(conststring &s1,conststring &s2,boolcomp(conststring &s1,conststring &s2)){

if(comp(s1, s2)){

cout<<"Yes"<<endl;

}else{

cout<<"No"<<endl;

}

}

// 或者以指针的形式来声明函数形参, 这种定义与上面那种定义是等价的

intpackageFunc(conststring &s1,conststring &s2,bool(*cp)(conststring &,conststring &));

考虑到这样的形式参数声明太过冗长,可以使用typedef和decltype来简化操作,比如上面代码又可以这样写

1

2

3

4

5

6

typedefboolFunc(conststring&,conststring&);

intpackageFunc(conststring &s1,conststring &s1, Func);

// 或者写成这样,这条语句与上面的typedef声明语句等价

typedefdecltype(compareLength) Func2;

intpackageFunc(conststring &s1,conststring &s1, Func2)

或者定义成函数指针的形式

1

2

3

4

5

6

typedefbool(*fp)(conststring &,conststring &);

intpackageFunc(conststring s1,conststring s2, fp);

// 定义成函数指针的形式,与上面的声明等价

typedefdecltype(compareLength) *fp_ptr;

intpackageFunc(conststring s1,conststring s2, fp_ptr);

或者还可以这样写

1

usingfp =bool(*)(conststring &,conststring &);

typedef:是自定义数据类型的声名符,可以用于定义自己的数据类型,与using有相似的地方

decltype:它返回一个函数类型,即对传入的函数类型进行处理,返回一个返回类型和形参定义都与传入函数相等的函数类型,但是它无法将返回的函数类型自动转变为函数指针,所以再需要函数指针是要加*号

函数指针作为返回值

函数指针也可作为返回值,比如传统的Unix进程间通过signal通信的方式的signal函数就会返回函数指针类型,如

1

2

3

4

#include<signal.h>

函数指针 =signal(SIGABRT, 函数句柄);

// 其返回的就是一个函数指针,即上一个与这个信号绑定的函数句柄,如果是第一次绑定返回NULL

但是函数类型不可,依据上面的简要声明,

1

2

3

4

5

6

usingF =int(int*,int);

usingPF =int(*)(int*,int);

PF f1(int);// 正确,PF为指函数的指针

F f2(int);// 错误,F为函数类型

F* f3(int);// 正确,显式的制定了函数返回函数指针的形式

也可以直接声明,但是不太好理解,会导致代码的可读性差,不建议这样做

1

int(*f1(int))(int*,int);

还可以以后置形式声明一个函数返回一个函数指针类型

1

auto f1(int) ->int(*)(int*,int);

练习

编写函数的声明,令其接收两个int形参并且返回类型也是int;然后声明一个vector对象,零其元素执行函数的指针

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#include<iostream>

#include<vector>

usingnamespacestd;

intfunc1(inta,intb){

// 加法

returna+b;

}

intfunc2(inta,intb){

// 减法

returna - b;

}

intmain(intargc,char*argv[]){

decltype(func1) *p1 = func1, *p2 = func2;

vector<decltype(func1)*> s = {p1,p2};

inta = 10,b = 5;

printf("add:[%d + %d = %d]\n", a, b, s[1](a,b));

printf("sub:[%d - %d = %d]\n", a, b, s[1](a,b));

}

1

add:[10 + 5 = 5]sub:[10 - 5 = 5]

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询