C++ 函数调用操作符 () 、 函数对象


除了函数调用操作符之外,重载操作符的形参数目(包括成员函数的隐式 this 指针)与操作符的操作数数目相同。函数调用操作符可以接受任意数目的操作数。

重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。又称仿函数。

函数调用操作符通常结合函数对象一起使用,在STL排序中应用广泛。


为什么函数对象比函数指针效率高 ?

函数对象比函数指针高: 这是由于使用函数对象可以在编译时确定调用的函数,比运行时确定效率高些。而且使用函数对象还有机会内联展开,从而避免了函数调用的开销。(from:http://bbs.csdn.net/topics/350142727

函数指针的主要性能缺点是 它的间接引用使其不能被内联。


转自:重载函数调用操作符


函数调用操作符是(),因此,此操作符的函数重载是operator()()。重载函数调用操作符的类对象称为函数对象或仿函数(functor),因为我们可以像使用函数名一样使用对象名。先来看一个简单的例子。下面是重载了函数调用操作符的一个类:

class Area  
{  
public:  
    int operator()(int length, int width) { return length*width; }  
}; 

此类中的操作符函数计算一个面积,它是两个整数实参的乘积。为了使用此操作符函数,只需要创建一个类型为Area的对象,例如:

Area area;                                     // Create function object
int pitchLength(100), pitchWidth(50);  
int pitchArea = area(pitchLength, pitchWidth); // Execute function call overload 

第一条语句创建第三条语句中使用的area对象,第三条语句使用此对象来调用对象的函数调用操作符。在此例中,返回的是足球场的面积。

当然,也可以将一个函数对象传递给另一个函数,就像传递任何其他对象一样。看看下面这个函数:

void printArea(int length, int width, Area& area)  
{  
    cout << "Area is " << area(length, width);  
} 

下面是使用此函数的语句:

printArea(20, 35, Area()); 

这条语句调用printArea()函数,前两个实参分别指定矩形的长和宽。第三个实参调用默认构造函数,以创建一个Area对象,函数中计算面积时要使用此Area对象。因此,函数对象提供了一种方式,可以将函数作为实参传递给另一个函数。与使用函数指针相比,这种方式既简单又容易。

注意:第10章将学习std::function<>模板,它为传递函数提供了更大的灵活性。

定义函数对象的类一般不需要数据成员,也没有定义的构造函数,因此创建和使用函数对象的开销是最小的。函数对象类通常也定义为模板,因为这会增加灵活性,本章稍后将会介绍这一点。


以下为测试代码

#include "stdafx.h"
#include <iostream>

using namespace std;

//
class FuncBase
{
public:
    void operator()(int i)
    {
        cout<<"FuncBase : "<<i<<endl;
    }
};

class FuncExtd : public FuncBase
{
public:
    void operator()(int i)
    {
        cout<<"FuncExtd : "<<i<<endl;
    }
};

void test(int i, FuncBase fun)
{
    fun(i);
}

void test1(int i, FuncBase& fun)
{
    fun(i);
}

//
class FBase
{
public:
    virtual void operator()(int i)
    {
        cout<<"FBase : "<<i<<endl;
    }
};

class FExtd : public FBase
{
public:
    virtual void operator()(int i)
    {
        cout<<"FExtd : "<<i<<endl;
    }
};

void test2(int i, FBase fun)
{
    fun(i);
}

void test3(int i, FBase& fun)
{
    fun(i);
}
//

int _tmain(int argc, _TCHAR* argv[])
{
    // 重载函数调用操作符 示声明为虚函数
    test(0, FuncBase());
    test(0, FuncExtd());
    test1(1, FuncBase());
    test1(1, FuncExtd());

    // 重载函数调用操作符 声明为虚函数
    test2(2, FBase());
    test2(2, FExtd());
    test3(3, FBase());
    test3(3, FExtd());
    return 0;
}




  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值