函數(shù)指針
函數(shù)指針指向的是函數(shù)而非對象。函數(shù)指針指向某種特定類型狭姨,該函數(shù)類型由其返回類型和形參類型共同決定,與名字無關(guān)苏遥。
聲明指向某函數(shù)的指針饼拍,只需要用指針替換函數(shù)名即可。注意類型和形參都需要完整且完全一致暖眼。
例如:bool (*pf)(const string&, const string&)
:名稱為pf惕耕,是個指針,右側(cè)是形參列表诫肠,表示pf指向函數(shù)司澎,左側(cè)是返回類型。其中栋豫,指向的函數(shù)的形參都是對const string的引用挤安。返回值是bool。
注意:bool* pf(const string&, const string&)
表示名稱為pf的函數(shù)返回值為bool*
Iパ臁蛤铜!
使用函數(shù)指針
把函數(shù)名作為一個值使用時,該函數(shù)自動轉(zhuǎn)換為指針丛肢。如:
pf = foo; //pf指向函數(shù)foo
pf = &foo; //等價
可以直接使用指向函數(shù)的之后著呢調(diào)用函數(shù)而不解引用指針:
pf("hello")
指向不同函數(shù)類型的指針間不存在轉(zhuǎn)換規(guī)則围肥。但是可以通過賦nullptr表示該指針沒有指向任何函數(shù)(但類型依然存在)
重載函數(shù)的指針
使用重載函數(shù),上下文必須清晰界定到底選用哪個函數(shù)蜂怎。
函數(shù)指針形參
不能定義函數(shù)類型的形參穆刻,但是形參可以是指向函數(shù)的指針。此時形參看似函數(shù)類型杠步,但實際上是當(dāng)成指針使用氢伟。也可以直接將函數(shù)名作為形參,會自動轉(zhuǎn)為指針:
void func(int a, char* b, string pf(const string&))
//等價于
void func(int a, char* b, string (*pf)(const string&))
//直接用函數(shù)名
void func(int a, char* b, string foo)
使用typedef定義上述類型避免冗雜:
typedef bool (*funcPointer)(const string&);
//等價于:
using funcPointer = bool (*)(const string&);
//等價于:
typedef decltype(foo)* funcPointer;
//去掉解引用就是函數(shù)的typedef幽歼。
返回指向函數(shù)的指針
最簡單的方法是使用別名:
using F = int(int*, int);
//PF是指向函數(shù)的指針朵锣,即返回類型。
using PF = int(*)(int*, int);
PF p1(int); //正確
F f1(int); //錯誤甸私,實際是函數(shù)
F* p2(int); //正確
int (*f2(int))(int*, int) //正確
int (*f2(int))(int*, int)
理解為:f2(int)
是一個函數(shù)诚些,返回一個 int*
指針。該指針指向形參為(int*, int)
的函數(shù)皇型。
另外诬烹,可以使用尾置返回類型的方式助析,左邊是函數(shù)定義,右邊是函數(shù)的返回值椅您。
auto f3(int) -> int (*)(int*, int);
將auto和decltype用于函數(shù)指針類型
若明確知道返回的函數(shù)是哪一個外冀,就可以直接用decltype(function name)
的形式定義一個返回該函數(shù)的函數(shù)。