1. 程式人生 > >C/C++函式指標的用法

C/C++函式指標的用法

 

一 函式指標介紹

 

  函式指標指向某種特定型別,函式的型別由其引數及返回型別共同決定,與函式名無關。舉例如下:

  1. int add(int nLeft,int nRight);//函式定義  

 該函式型別為int(int,int),要想宣告一個指向該類函式的指標,只需用指標替換函式名即可

  1. int (*pf)(int,int);//未初始化  

  則pf可指向int(int,int)型別的函式。pf前面有*,說明pf是指標,右側是形參列表,表示pf指向的是函式,左側為int,說明pf指向的函式返回值為int。則pf可指向int(int,int)型別的函式。而add型別為int(int,int),則pf可指向add函式。

  1. pf = add;//通過賦值使得函式指標指向某具體函式  

  注意:*pf兩端的括號必不可少,否則若為如下定義:

  1. int *pf(int,int);//此時pf是一個返回值為int*的函式,而非函式指標  

二 標準C函式指標

 

 1函式指標的定義

   1.1 普通函式指標定義

  1. int (*pf)(int,int);  

  1.2 使用typedef定義函式指標型別

  1. typedef int (*PF)(int,int);  
  2. PF pf;//此時,為指向某種型別函式的函式指標型別,而不是具體指標,用它可定義具體指標</span>  

   

 2函式指標的普通使用

  1. pf = add;  
  2. pf(100,100);//與其指向的函式用法無異  
  3. (*pf)(100,100);//此處*pf兩端括號必不可少  

注意:add型別必須與pf可指向的函式型別完全匹配

 

 3函式指標作為形參

  1. //第二個形參為函式型別,會自動轉換為指向此類函式的指標  
  2. Void fuc(int nValue,int pf(int,int));  
  3.   
  4. //等價的宣告,顯示的將形參定義為指向函式的指標  
  5. Void fuc(int nValue,int (*pf)(int,int));  
  6. Void fuc(int nValue,PF);  


    形參中有函式指標的函式呼叫,以fuc為例:

  1. pf = add;//pf是函式指標  
  2. fuc(1,add);//add自動轉換為函式指標  
  3. fuc(1,pf);  

 

 4返回指向函式的指標

4.1 使用typedef定義的函式指標型別作為返回引數

  1. PF fuc2(int);//PF為函式指標型別  

    4.2 直接定義函式指標作為返回引數

  1. 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組合定義函式型別

  1. typedef decltype(add) add2;  

  decltype返回函式型別,add2是與add相同型別的函式,不同的是add2是型別,而非具體函式。

 

使用方法:

  1. add2* pf;//pf指向add型別的函式指標,未初始化  

    2.2 typedef與decltype組合定義函式指標型別

  1. typedef decltype(add)* PF2;//PF2與1.1PF意義相同  
  1. PF2 pf;// pf指向int(int,int)型別的函式指標,未初始化  

    2.3 使用推斷型別關鍵字auto定義函式型別和函式指標

  1. auto pf = add;//pf可認為是add的別名(個人理解)   
  2. auto *pf = add;//pf為指向add的指標   

 3函式指標形參

  1. typedef decltype(add) add2;  
  2. typedef decltype(add)* PF2;  
  3. void fuc2 (add2 add);//函式型別形參,呼叫自動轉換為函式指標  
  4. 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關鍵字

  1. decltype(add)* fuc2(int)//明確知道返回哪個函式,可用decltype關鍵字推斷其函式型別,  

  5 成員函式指標

 5.1普通成員函式指標使用舉例   

  1. class A//定義類A  
  2. {  
  3. private:  
  4.   
  5.        int add(int nLeft, int nRight)  
  6.   
  7.        {  
  8.               return (nLeft + nRight);  
  9.        }  
  10.   
  11. public:  
  12.   
  13.        void fuc()  
  14.   
  15.        {  
  16.               printf("Hello  world\n");  
  17.              
  18.        }  
  19. };  
  20.   
  21.    
  22. typedef void(A::*PF1)();//指標名前需加上類名限定  
  23.   
  24. PF1 pf1 = &A::fuc; //必須有&  
  25.   
  26. A a;//成員函式地址解引用必須附駐與某個物件地址,所以必須建立一個隊形  
  27.   
  28. (a.*pf1)();//使用成員函式指標呼叫函式  

 

     5.2繼承中的函式指標使用舉例

  1. class A  
  2. {  
  3. public:  
  4.        void fuc()  
  5.        {  
  6.               printf("Hello fuc()\n");  
  7.        }  
  8.   
  9.        void fuc2()  
  10.        {  
  11.               printf("Hello A::fuc2()\n");  
  12.        }  
  13. };  
  14.   
  15. class B:public A  
  16. {  
  17. public:  
  18.        virtual void fuc2()  
  19.        {  
  20.               printf("Hello B::fuc2()\n");  
  21.        }  
  22.   
  23. };  
  24.   
  25. typedef void(A::*PF1)();  
  26. typedef void(B::*PF2)();  
  27.   
  28. PF1 pf1 = &A::fuc;  
  29.   
  30. int main()         
  31. {  
  32.        A a;  
  33.        B b;  
  34.        (a.*pf1)();  //呼叫A::fuc  
  35.        (b.*pf1)();   //呼叫A::fuc  
  36.   
  37.        pf1 = &A::fuc2;  
  38.        (a.*pf1)();  //呼叫A::fuc2  
  39.        (b.*pf1)();  //呼叫A::fuc2  
  40.   
  41.        PF2 pf2 = &A::fuc2;   
  42.        (b.*pf2)(); //呼叫A::fuc2  
  43. }  

 

  6過載函式的指標

    6.1 過載函式fuc

  1. Void fuc();  
  2. Void fuc(int);  

  6.2 過載函式的函式指標

  1. void (*PF)(int) = fuc;//PF指向fuc(int)  
  2. int(*pf2)(int) = fuc;//錯誤沒有匹配的型別  


   注意:編譯器通過指標型別決定選取那個函式,指標型別必須與過載函式中的一個精確匹配。