C/C++函式指標的用法
一 函式指標介紹
函式指標指向某種特定型別,函式的型別由其引數及返回型別共同決定,與函式名無關。舉例如下:
- 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 |
|
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;//錯誤沒有匹配的型別
注意:編譯器通過指標型別決定選取那個函式,指標型別必須與過載函式中的一個精確匹配。