https://www.cnblogs.com/lvchaoshun/p/7806248.html
一 函數指針介紹
函數指針指向某種特定類型,函數的類型由其參數及返回類型共同決定,與函數名無關。舉例如下:
- int add(int nLeft,int nRight);//函數定義
該函數類型爲int(int,int),要想聲明一個指向該類函數的指針,只需用指針替換函數名即可:
- int (*pf)(int,int);//未初始化
則pf可指向int(int,int)類型的函數。pf前面有*,說明pf是指針,右側是形參列表,表示pf指向的是函數,左側爲int,說明pf指向的函數返回值爲int。則pf可指向int(int,int)類型的函數。而add類型爲int(int,int),則pf可指向add函數。
- pf = add;//通過賦值使得函數指針指向某具體函數
注意:*pf兩端的括號必不可少,否則若爲如下定義:
- int *pf(int,int);//此時pf是一個返回值爲int*的函數,而非函數指針
二 標準C函數指針
1函數指針的定義
1.1 普通函數指針定義
- int (*pf)(int,int);
1.2 使用typedef定義函數指針類型
- typedef int (*PF)(int,int);
- PF pf;//此時,爲指向某種類型函數的函數指針類型,而不是具體指針,用它可定義具體指針</span>
2函數指針的普通使用
- pf = add;
- pf(100,100);//與其指向的函數用法無異
- (*pf)(100,100);//此處*pf兩端括號必不可少
注意:add類型必須與pf可指向的函數類型完全匹配
3函數指針作爲形參
- //第二個形參爲函數類型,會自動轉換爲指向此類函數的指針
- Void fuc(int nValue,int pf(int,int));
- //等價的聲明,顯示的將形參定義爲指向函數的指針
- Void fuc(int nValue,int (*pf)(int,int));
- Void fuc(int nValue,PF);
形參中有函數指針的函數調用,以fuc爲例:
- pf = add;//pf是函數指針
- fuc(1,add);//add自動轉換爲函數指針
- fuc(1,pf);
4返回指向函數的指針
4.1 使用typedef定義的函數指針類型作爲返回參數
- PF fuc2(int);//PF爲函數指針類型
4.2 直接定義函數指針作爲返回參數
- 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組合定義函數類型
- typedef decltype(add) add2;
decltype返回函數類型,add2是與add相同類型的函數,不同的是add2是類型,而非具體函數。
使用方法:
- add2* pf;//pf指向add類型的函數指針,未初始化
2.2 typedef與decltype組合定義函數指針類型
- typedef decltype(add)* PF2;//PF2與1.1PF意義相同
- PF2 pf;// pf指向int(int,int)類型的函數指針,未初始化
2.3 使用推斷類型關鍵字auto定義函數類型和函數指針
- auto pf = add;//pf可認爲是add的別名(個人理解)
- auto *pf = add;//pf爲指向add的指針
3函數指針形參
- 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關鍵字
- decltype(add)* fuc2(int)//明確知道返回哪個函數,可用decltype關鍵字推斷其函數類型,
5 成員函數指針
5.1普通成員函數指針使用舉例
- 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繼承中的函數指針使用舉例
- class A
- {
- public:
- void fuc()
- {
- printf("Hello fuc()\n");
- }
- void fuc2()
- {
- printf("Hello A::fuc2()\n");
- }
- };
- class B:public A
- {
- public:
- virtual 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)(); //調用A::fuc
- (b.*pf1)(); //調用A::fuc
- pf1 = &A::fuc2;
- (a.*pf1)(); //調用A::fuc2
- (b.*pf1)(); //調用A::fuc2
- PF2 pf2 = &A::fuc2;
- (b.*pf2)(); //調用A::fuc2
- }
6重載函數的指針
6.1 重載函數fuc
- Void fuc();
- Void fuc(int);
6.2 重載函數的函數指針
- void (*PF)(int) = fuc;//PF指向fuc(int)
- int(*pf2)(int) = fuc;//錯誤沒有匹配的類型
注意:編譯器通過指針類型決定選取那個函數,指針類型必須與重載函數中的一個精確匹配。