首页 > 程序人生 > 函数指针(function pointer)使用详解

函数指针(function pointer)使用详解

函数指针(function pointer),是一个让人既爱又恨的东东,爱的是,它的确是很强大,用的好的话,能写出结构很清晰的代码,比较常见的就是一些事件处理模型中用到的处理事件的回调函数等。恨的是,函数指针的使用,是一个比较高级的话题,对一般的程序员来说,这个语法不容易掌握,用的时候容易出错,调试的时候还比较麻烦。C++中提出了虚函数(virtual function),有人说可以用虚函数功能来替代函数指针了,函数指针可以被抛弃了,但是,我们知道,使用虚函数有额外的开销的,因此,很多追求高效率的程序员还是更加钟爱函数指针。下面就函数指针的使用,进行举例一一说明:

1. 最普通的使用方式,函数指针指向普通函数的情况

#include <stdio.h>
 
typedef void (*Handle)(void *); 
 
void HandleChar(void * pArg)
{
    printf("%c\n", *(char *)pArg);
}
 
void HandleInt(void * pArg)
{
    printf("%d\n", *(int *)pArg);
}
 
void TestHandle(void * pArg, Handle pHandle)
{
    (*pHandle)(pArg);
}
 
int main()
{
    char bCh = 'I';
    TestHandle(&bCh, &HandleChar);
 
    int nNum = 100;
    TestHandle(&nNum, &HandleInt);
}

2. 函数指针指向静态类成员函数的情况

#include <stdio.h>
 
class Test
{
public:
 
    static void HandleChar(void * pArg)
    {   
        printf("%c\n", *(char *)(pArg));
    }   
 
    static void HandleInt(void * pArg)
    {   
        printf("%d\n", *(int *)(pArg));
    }   
};
 
typedef void (*Handle)(void *); 
 
void TestHandle(void * pArg, Handle pHandle)
{
    (*pHandle)(pArg);
}
 
int main()
{
    char bCh = 'I';
    TestHandle(&bCh, &Test::HandleChar);
 
    int nNum = 100;
    TestHandle(&nNum, &Test::HandleInt);
}

3.函数指针指向普通的类成员函数,在类成员函数中的调用的情况

#include <stdio.h>
 
class Test
{
public:
 
    typedef void (Test::*Handle)(void *); 
 
    void HandleChar(void * pArg)
    {   
        printf("%c\n", *(char *)(pArg));
    }   
 
    void HandleInt(void * pArg)
    {   
        printf("%d\n", *(int *)(pArg));
    }   
 
    void TestHandle(void * pArg, Handle pHandle)
    {   
        (this->*pHandle)(pArg);
    }   
};
 
int main()
{
    Test oTest;
    char bCh = 'I';
    oTest.TestHandle(&bCh, &Test::HandleChar);
 
    int nNum = 100;
    oTest.TestHandle(&nNum, &Test::HandleInt);
}

3.函数指针指向类成员函数,在全局函数中调用的情况。

#include <stdio.h>
 
class Test
{
public:
 
    void HandleChar(void * pArg)
    {   
        printf("%c\n", *(char *)(pArg));
    }   
 
    void HandleInt(void * pArg)
    {   
        printf("%d\n", *(int *)(pArg));
    }   
};
 
typedef void (Test::*Handle)(void *); 
 
void TestHandle(Test &obj, void * pArg, Handle pHandle)
{
    (obj.*pHandle)(pArg);
}
 
int main()
{
    Test oTest;
    char bCh = 'I';
    TestHandle(oTest, &bCh, &Test::HandleChar);
 
    int nNum = 100;
    TestHandle(oTest, &nNum, &Test::HandleInt);
}

通过上面的例子,以及结合我自己在写代码过程中一的一些经验,我觉得,在使用函数指针时,需要注意以下几点:
1. 在使用函数指针的时候,最好用typedef进行类型定义,这样语法看起会来会比较清晰,减少出错概率
2. 当类成员函数作为函数的函数指针型参数时,一定要加上类名做其作用域前缀,如上面的Test::HandleChar和Test::HandleInt
3. 当函数指针为在成员函数类型时,调用某个确定的函数时,一定要显式地指名其所在的域,如上面的(this->*pHandle)(pArg)和(obj.*pHandle)(pArg)

OK, that’s all, good luck!

分类: 程序人生 标签: ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
您必须在 登录 后才能发布评论.