AI智能
改变未来

c++中的函数指针


引言

函数指针指向的是函数而不是对象。函数指针指向某种特定类型,就像我们可以定义指向int变量的指针,指向char变量的指针以及指向string变量的指针,函数指针指向的这种特定类型由函数的返回类型形参类型共同决定,而与函数名无关。

例如有一个函数

compare

声明如下:

bool compare(const string &, const string &);

若要定义指向该函数的指针,那么应该像这样:

bool (*pf)(const string &,const string &);

依然遵循由内而外的原则阅读声明:

  • 首先
    (*pf)

    表明变量

    pf

    是指针类型;

  • 而后面的
    (const string &,const string &)

    是形参列表,表明指针

    pf

    指向一个函数,该函数的形参列表如上;

  • 最后,最左边的
    bool

    表明这个函数的返回类型是

    bool

Note:

bool *pf(const string &,const string &);

对比上面的这个声明和上上个声明,差别在

(*pf)

*pf

上。

(*pf)

指明

pf

是指针类型,而

*pf

对应的那条声明指明

pf

是个函数,函数的返回类型是

bool *

。因此,声明指向函数的指针时,

(*pf)

两端的括号必不可少,至于差别大家也看到了。

使用函数指针

当我们把函数名作为一个值使用时,该函数自动转换成指针。例如对上面的

compare

函数和函数指针

pf

,若要使

pf

指向

compare

函数,我们有:

pf = compare;  //函数名自动转换为指针pf = &compare; //等价的赋值,&可选。pf = 0;  //表明pf不指向任何函数pf = nullptr;   //与上句等价

并且,我们能够直接使用指向函数的指针调用该函数,不一定非要解引用指针。例如:

bool b1 = pf("你好", "Fuck!");  //直接使用指向函数的指针调用函数bool b2 = (*pf)("你好", "Fuck!"); //等价的调用。先解引用指针,再调用函数。bool b2 = *pf("你好", "Fuck!"); //错误的调用。函数调用运算符()的优先级高于解引用运算符*的优先级。/*bool b2 = *pf("你好", "Fuck!");//等价于以下两条语句:bool tmp = pf("你好", "Fuck!"); //即调用pf指向的函数。bool b2 = *tmp; //对tmp解引用。显然错误,因为不能对bool类型解引用//如果compare函数返回char *类型,则语句bool b2 = *pf("你好", "Fuck!");反而正确*/bool b3 = compare("你好", "Fuck!"); ////等价的调用。直接使用函数。

我们再来加深下对函数指针指向的类型的理解:假设有三个函数声明如下:

bool compare1(const string &, const string &);bool compare2(const string &, const string &);bool compare3(const int &, const int &);

函数指针

pf

如下:

bool (*pf) (const string &, const string &);pf = compare1;  //正确pf = compare2;  //正确pf = compare3;  //错误,形参不匹配

(重载函数)的指针

考虑重载的函数:

void f(int *);void f(int);void (*pf) (int) = f; //pf指向void f(int);

编译器通过指针类型决定指向哪个重载函数,指针类型必须与重载函数中的某一个精确匹配(返回类型和形参列表精确匹配)。

将函数指针作为形参

就如我们不能定义数组类型的形参一样,我们不能定义函数类型的形参,但是形参可以是指向函数的指针。形参看起来是函数类型,实际上当成指针使用。例如:

//第三个形参是函数类型,但会自动转换为指向函数的指针。即,pf是指向函数的指针。void f(const string &s1, const string &s2, bool pf(const string &, const string &));//等价的声明,显式地将形参定义为指向函数的指针。void f(const string &s1, const string &s2, bool (*pf)(const string &, const string &));

直接把函数作为实参时,会自动转换为指针。

//自动将函数compare转换为指向该函数的指针。f("你好", "Fuck", compare);

将指向函数的指针作为返回类型

就如我们不能在函数中返回数组类型一样,我们不能直接返回函数类型,但可以返回指向函数的指针。以下声明一个返回函数指针的函数:

int (*f(int)) (int *, int);

从内而外阅读声明,首先

*f(int)

表明

f

是函数,参数是

int

,返回指针类型。

(int *, int)

表明指针指向函数一个,且参数列表为

(int *, int)

,最左边的int表明指向的该函数返回

int

亦可以使用尾置返回类型的方式:

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

该声明与上一条声明等价。

将decltype用于函数指针类型

如果我们明确知道返回的函数是哪一个,就能使用

decltype

简化书写函数指针。

decltype(compare) *p; //p是一个指向compare函数对应类型(只是返回类型和形参,函数名不属于类型的一部分)的指针类型decltype(compare) * f(); //函数声明,f是一个函数,没有形参,返回类型为指向compare函数对应类型(只是返回类型和形参,函数名不属于类型的一部分)的函数指针类型

Note:

decltype

作用于某个函数时,返回函数类型而不是指针类型,需要显式加上

*

表明我们需要指针类型。

声明:c++ Basic是对《C++ Primer 第五版》的个人总结与疑难解释,主要用于个人日后复习。如果想要深入了解更多,请支持正版。

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » c++中的函数指针