c++ 仿函数(function object)和函数指针的差别

        所谓仿函数,是定义了operator()的对象,下面这个例子:

FunctionObject fo;
 

          fo();

其中表达式fo()是调用仿函数fo的operator()。而非调用函数fo().

你可以将仿函数看做一般函数,只不过用的是一种更复杂的撰写手段:并非将所有语句放在函数体中:

void fo() {
               statements;
}

而是在仿函数类别的operator()体内撰写程序代码。

class  FunctionObject {
          public:
                    void operator() {
                                  statements;
                    }
};

而函数指针就先对来说比较简单,

void (*ptrA)(void);

void funcA(void);

ptrA = funcA;//为函数指针赋值
void (*ptrA)(void);//这就相当于调用funcA

我主要说一下这俩者在写模板的时候的区别,先看代码吧:

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

template <typename InputIterator, typename T >
inline T accumulate(InputIterator first, InputIterator last, T init, T (*ptrA)(T, T)) {//函数指针
    while (first != last) {
        init = (*ptrA)(init, *first);
        ++first;
    }

    return init;
}

int funcA(int x, int y)
{
    return x + y;
}

int main(void) 
{
    int a[5] = {2, 5, 7, 9, 11};

    random_shuffle(&a[0], &a[5]);
    int x = ::accumulate(&a[0], &a[5], 0, funcA);
    cout << x << endl;

    return 0;
}

这里就是计算a数组里面全部的和,放在x变量里面。

       首先,这个函数的原型是T (*ptrA)(T x, T y);如果我想提升我处理数据的速度,让时间少浪费由于函数值传递引起的拷贝上,于是我需要这样写函数 T funcA(const int& x, const int& y)。这样写的话,我们原来的函数T (*ptrA)(T x, T y)就不能匹配这个函数,于是我们就要重载函数。还有就是效率问题,函数指针的调用,我们的电脑需要做很多工作,比如说保存当前的寄存器值,传递参数,返回值,返回到函数调用地方继续执行等。

      幸运的是,这一切问题都可以通过仿函数来解决,如下:

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

template <typename InputIterator, typename T, typename FunObject>
inline T accumulate(InputIterator first, InputIterator last, T init, FunObject object) {//函数对象
    while (first != last) {
        init = object(init, *first);
        ++first;
    }

    return init;
}

template < typename T>
class Test {
    public:
    T operator()(const T& x, const T& y) {
        return x + y;
    }
};

int main(void) 
{
    int a[5] = {2, 5, 7, 9, 11};

    random_shuffle(&a[0], &a[5]);
    int x = ::accumulate(&a[0], &a[5], 0, Test<int>());
    cout << x << endl;

    return 0;
}

 

这样就解决了效率和函数重载的问题了。

posted @ 2013-05-18 22:35  露天坝  阅读(3540)  评论(0)    收藏  举报