zoukankan      html  css  js  c++  java
  • 函数指针(待修改)

    指向函数的指针变量。

    每个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数。

    用途:

    调用函数和做函数的参数,比如回调函数。

    示例:

    1 char * fun(char * p)  {…}       // 函数fun
    2 
    3 char * (*pf)(char * p);             // 函数指针pf
    4 
    5 pf = fun;                        // 函数指针pf指向函数fun
    6 
    7 pf(p);                        // 通过函数指针pf调用函数fun

    一、函数指针

    指向某种特定的类型,这个类型由函数返回的类型决定。

    int add(int nLeft,int nRight);//函数定义  

    这个函数类型是int(int,int),声明一个指向这类函数的指针:

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

    pf可指向int(int,int)类型的函数。

    给函数指针赋值:

    pf = add;//通过赋值使得函数指针指向某具体函数 

    二、c中函数指针

    1、定义

    //方法二
    int (*pf)(int,int);  
    //方法二
    typedef int (*PF)(int,int);  
    PF pf;//此时,为指向某种类型函数的函数指针类型,而不是具体指针,用它可定义具体指针

    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、返回指向函数的指针

    使用typedef定义的函数指针类型作为返回参数:

    PF fuc2(int);//PF为函数指针类型  

    直接定义函数指针作为返回参数

    int (*fuc2(int))(int,int);//显示定义  

    按照有内向外的顺序阅读此声明语句。fuc2有形参列表,则fuc2是一个函数,其形参为fuc2(int),fuc2前面有*,所以fuc2返回一个指针,指针本身也包含形参列表(int,int),因此指针指向函数,该函数的返回值为int.

    总结:fuc2是一个函数,形参为(int),返回一个指向int(int,int)的函数指针。

    三、c++中定义函数指针

    C++完全兼容C,则C中可用的函数指针用法皆可用于C++。

    1、定义函数类型

    typedef与decltype组合定义函数类型:

    typedef decltype(add) add2;  

    decltype返回函数类型,add2是与add相同类型的函数,不同的是add2是类型,而非具体函数。

    add2* pf;//pf指向add类型的函数指针,未初始化  

    2、定义函数指针类型

    typedef decltype(add)* PF2;//PF2与1.1PF意义相同  
    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 ");  
    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() ");  
    7.        }  
    8.   
    9.        void fuc2()  
    10.        {  
    11.               printf("Hello A::fuc2() ");  
    12.        }  
    13. };  
    14.   
    15. class B:public A  
    16. {  
    17. public:  
    18.        virtual void fuc2()  
    19.        {  
    20.               printf("Hello B::fuc2() ");  
    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;//错误没有匹配的类型  


       注意:编译器通过指针类型决定选取那个函数,指针类型必须与重载函数中的一个精确匹配。

  • 相关阅读:
    Android开发之JSON数据发送与获取
    Layouts之TableLayout表格布局
    Layouts之GridLayout网格布局
    Android WiFi模块学习
    关于Fragment的讲解及适配
    hive 压缩全解读(hive表存储格式以及外部表直接加载压缩格式数据);HADOOP存储数据压缩方案对比(LZO,gz,ORC)
    Dynamics CRM SQL转化为FetchXML的在线转化工具
    Dynamics CRM 通过Odata创建及更新记录各类型字段的赋值方式
    shell命令执行hive脚本(hive交互,hive的shell编程)
    CRM 2013 Script Loading Deep Dive
  • 原文地址:https://www.cnblogs.com/pacino12134/p/11255176.html
Copyright © 2011-2022 走看看