函数指针、函数对象、仿函数比较与入门


前言

在平常的C/C++代码编程中, 我们经常会碰到函数指针(Function Pointer)这个概念, 在很多C++代码中,经常使用函数对象(Functors,Function Objects)等特性,也的甚至还会看到更高级的比如boost::bind, std::bind一类的, 这些东西, 初一看, 会觉得很高级(好吧,它确实很高级),对初学者造成很大的困惑与不解(好吧,我也是初学者),下面就来详解一下这些知识的一些特点与应用场合,其中如果有什么不对的地方, 还望各位大牛批评指教, 以免误导他人。 

函数指针

在讲函数指针之前, 先讲一个分清C/C++中各种术语的小技巧,比如指针常量,常量指针、函数指针、指针函数等许多概念,以函数指针为例,分成两部分来看,前面修饰词是函数,后面是指针,所以可这么认为, 这是一个指针, 既然是指针,就一定需要指向一个地址,那个这个地址的类型是什么呢, 就由前面的那个修饰词”函数“来标识了,因为可理解为:函数指针,它是一个指针,这个指针指向一个函数的地址。 同理, 常量指针也一样,它是一个指针, 指向的是一个常量的地址。数组指针, 一个指针,指向的是一个数组的地址,也就是首地址。

废话说了这么多, 现在我们来说一个小例子,我们要计算0--10的和,通常我们都是定义一个sum = 0 值,然后循环将值加到这个sum身上, 现在我们加个需求,我要把每次循环的值都打印出来, 如果用函数指针作为参数传递的话, 我们可以这么写
#include  
using namespace std;  
  
typedef void (*func)(int );  
  
void print(int value)  
{  
    printf("%d ", value);  
}  
  
void add(int &sum, int index, func pFunc)  
{  
    sum += index;  
    pFunc(sum);  
}  
  
int main(void)  
{     
    int sum = 0;  
    for (int i = 0; i < 10; i++)  
    {  
        add(sum ,i, print);  
    }  
  
    return 0;  
}  

打印结果为:
0 1 3 6 10 15 21 28 36 45 请按任意键继续. . .

从上面可以看出,我们可以将一个函数名作为一个参数传递,这就是函数指针的大概用法,具体详细用法,请大家自行谷歌, 重点是下面的两个东西。

仿函数、函数对象(Functors、Function Objects)

首先,我们看看在《C++标准程序库》一书中对仿函数的解释:任何东西,只要其行为像函数,就可以称之为仿函数。我们再看我们的下面这句代码:
for (int i = 0; i < 10; i++)  
{  
   add(sum ,i, print);
}  
我们看到这个print,有木有想过, 它可以是一个类的对象呢,比如,MyPrint print这种形式,只要他具备某种函数行为就可以了, 所谓函数行为,,是指可以使用”小括号传送参数, 调用某个东西”,比如function1(arg1,arg2);(摘自《C++标准程序库》),所以只要我们定义的对象可以有这种行为就可以了,因此我们必须要重载()操作符,以让对象的行为像函数。因为一个对象,具备像函数一样的行为, 就称为函数对象。

下面我们就把上面用函数指针改成用函数对象的形式
#include "stdafx.h"  
  
#include  
using namespace std;  
  
class MyPrint  
{  
public:  
    void operator()(int value) const  
    {  
        printf("%d ", value);  
    }  
};  
  
void add(int &sum, int index, MyPrint &pFunc)  
{  
    sum += index;  
    pFunc(sum);  
}  
  
int main(void)  
{     
    int sum = 0;  
    MyPrint print;  
  
    for (int i = 0; i < 10; i++)  
    {  
        add(sum ,i, print);  
    }  
  
    return 0;  
}  

如果讲到这里, 我们就结束了的话, 肯定会不禁要问, 这两者有什么区别,既然有了函数指针, 还要函数对象干嘛。
首先,一个类,是数据以及对数据操作的行为的集合, 而我们现在的函数对象,只拥有方法, 而没有使用它的数据,但是在函数指针,是无法保存数据的, 所以,函数对象比函数指针功能更强, 因为它可以保存数据,利用这一特性, 是函数指针无法比拟的优势。


你可能感兴趣的:(C++)