6函数之函数指针
函数类型由它的返回类型与形参类型共同决定:
1 //比较两个string对象的长度 2 bool lengthCompare(const string&,const string &);
上述函数的类型是:bool (const string &,const string &),如果想声明一个指向该函数的指针,只需要用指针替换函数名即可。如下:
bool (*pf)(const string &,const string &); //pf指向一个函数,该函数的参数是两个const string 的引用,返回值是bool类型。
我们观察上述声明:pf前有个*,说明它是一个指针;右侧是形参列表,说明pf指向的是函数,其中该函数的参数是const string的引用,返回值是bool类型。
如果不加“括号”,则pf是一个返回值为bool*的函数,意思就错了。
一、使用函数指针:
1.当我们把函数名作为一个值使用时,该函数自动地转换为指针。
pf = lengthCompare; //pf指向名为lengthCompare的函数
pf = &lengthCompare; //和上式等价,其中“&”取地址符是可选的
2.我们能够直接使用指向函数的指针调用该函数,而无需提前解引用指针。
bool b1 = pf("hello","goodbay"); //调用lengthCompare函数
bool b2 = (*pf)("hello","goodbay");//和上式一样的等价调用
bool b3 = lengthCompare("hello","goodbay");//和上式一样的等价调用
在指向不同函数类型(不同返回类型或不同形参类型)的指针间不存在转换规则;
二、(重载函数)指针:
当我们使用重载函数时,如果定义了指向重载函数的指针,则指针类型必须与重载函数中的某一个精确匹配。
void ff(int *);
void ff(unsigned int);
void (*pf1) (unsigned int) = ff; //针对上述两个重载函数,pf1指向ff(unisgned)
三、将函数指针作为形参来使用:
形参:
虽然不能把函数作为形参,但是可以可以把指向函数的指针作为形参,就像不能把数组作为形参,但是可以把指向数组的指针作为形参一样使用。
void useBigger(const string &s1,const string &s2,bool pf(const string &,const string &)); //第三个参数是函数类型,它会自动将函数类型转换为为指向函数的额指针
void useBigger(const string &s1,const string &s2,bool(*pf)(const string &,const string &));//显式的将形参定义成指向函数的指针
实参:
我们能够直接将函数作为形参使用,此时函数会自动转换为指针:
useBigger(s1,s2,lengthCompaer); //自动将函数转换为指向该函数的指针
使用类型别名能够解决上述函数声明较为冗长的问题:
typedef bool Func(const string&,const string&); //Func是函数类型
typedef decltype(lengthCompaer) Func2; //等价类型
typedef bool(*FuncP)(const string &,const string&); //指向函数的指针
typydef decltype(lengthCompare)*FuncP2; //等价类型
void useBigger(const string &,const string &,Func); //编译器将Func自动转换为指向函数类型的指针
void useBigger(const string&,const string&,FuncP2);
四、返回指向函数的指针:
和数组类似,虽然不能返回一个函数,但是可以返回一个指向函数的指针,但是我们必须将函数返回类型写成指针形式,编译器不会自动将函数返回类型当成对应的指针类型处理。
using F = int(int*,int ); //F是函数类型,不是指针
using PF = int(*)(int*,int); //PF是指针类型
PF f1(int) ; //正确,PF是指向函数的指针,f1返回指向函数的指针
F * f1(int); //正确,显示的指定返回类型是指向函数的指针