函数指针vs函数对象

在C/C++中,我们可以将函数当作普通的变量传递给另外一个函数以便定制函数的功能。比如实现排序功能的函数sort(),我们既可以选择从小到大的顺序也可以选择从大到小的顺序,只要传递给sort()不同的比较函数就可以了。不过,C和C++的做法不一样,前者采用函数指针,而后者采用函数对象。相比而言,C++的做法更值得推崇,它在性能上、状态维护上比C的做法灵活很多。

性能

对一个整型数组每个元素进行increment操作,分别用函数指针和函数对象的方法来实现,代码如下所示:

#include <stdio.h>
#include <stdlib.h>

template<class T>
void proc(int* s, int n, T f)
{
    for(int i = 0; i < n; ++i)
    {
        f(*(s + i));
    }
}
// 函数指针
void fInc(int& a)
{
    ++a;
}
// 函数对象
class Inc
{
public:
    void operator()(int& a)
    {
        ++a;
    }
};

int main()
{
    int ar[] = {0,1,2,3,4};
    proc(ar,sizeof(ar)/sizeof(int),fInc);
    // proc(ar,sizeof(ar)/sizeof(int),Inc());
    for(int i = 0; i < sizeof(ar)/sizeof(int); ++i)
        printf_s("%d ",ar[i]);
    printf_s("\n");
    system("pause");
}

函数对象之所以性能更高,是因为它本质上是class Inc的实例,proc()实际调用的是class Inc的成员方法,它缺省情况下是inline的。而函数指针必须经过thunk才能执行。

状态维护

函数对象善于维护函数的状态,因为class的成员变量可用来保存函数的状态。函数指针就只能借助于全局变量,灵活性、安全性都比不上函数对象。以下面的代码为例:

#include <iostream>
#include <algorithm>
#include <iterator>
//函数对象
class Countfrom
{
private:
    int &count;
public:
    Countfrom(int& n):count(n)
    {
    }
    int operator()()
    {
        return count++;
    }
};
// 函数指针
int s = 10;
int fCountfrom()
{
    return s++;
}

int main()
{
    int state(10);
    int ar[11];
    std::generate_n(ar,11,Countfrom(state));
    // std::generate_n(ar,11,fCountfrom);
    for(int i = 0; i < 11; ++i)
        std::cout<<ar[i]<<std::endl;
    system("pause");
}

从上面的例子就不难看出函数对象和函数指针在维护状态上的差别。函数指针必须要借助于全局变量才能维护状态,而函数对象直接用自己内部的count来维护,更加灵活、安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值