c++ 指針函數

https://www.cnblogs.com/lvchaoshun/p/7806248.html


一 函數指針介紹


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

  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;//錯誤沒有匹配的類型  


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


發佈了21 篇原創文章 · 獲贊 16 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章