C++面向对象操作符重载:调用操作符和函数对象

 1、定义了调用操作符的类,其对象常称为函数对象,即它们是行为类似函数的对象。

     可以为类类型的对象重载函数调用操作符。一般为表示操作的类重载调用操作符。函数调用操作符必须声明为成员函数。一个类可以定义函数调用操作符的多个版本,由形参的数目或类型加以区别。

例如,可以定义名为 absInt 的结构,该结构封装将 int 类型的值转换为绝对值的操作:

class absInt
{
public:
    int operator() (int val) 
    { 
        return val < 0 ? -val : val; 
    }
};

调用的情况如下所示:

absInt m_abs;
int num = m_abs(-5);

2、函数对象常常用作算法的实参,下面是一个简单的例子:

比如我们有个存储字符串的vector<string> words; 我们想计算其中字符数大于6的个数, 我们现在使用标准库的函数count_if来计算. count_if最后传入处理函数,函数形式like this:

 bool funcName(const string &s) ;

此函数只接受一个参数,并且是count_if来为你传入, 好,下面我们写个比较函数:

 // determine whether a length of a given word is 6 or more 
 bool GT6(const string &s) 
 { 
     return s.size() >= 6; 
 }

这样来调用就ok了

vector<string>::size_type wc = count_if(words.begin(), words.end(), GT6); 

上面的程序将6固化在了GT函数的定义之中。理想的状况是我们可以和任意长度做比较,那么对上面的类进行一下改造就可以了:

 // determine whether a length of a given word is longer than a stored bound 
class GT_cls 
{ 
public: 
    GT_cls(size_t val = 0): bound(val) { } 
    bool operator()(const string &s){ return s.size() >= bound; } 
private: 
    std::string::size_type bound; 
}; 

我们可以按照下面的方式来调用:

//大于6个
cout << count_if(words.begin(), words.end(), GT_cls(6)) << " words 6 characters or longer" << endl;
//大于5个
cout << count_if(words.begin(), words.end(), GT_cls(5)) << " words 5 characters or longer" << endl;
//循环体
for (size_t i = 0; i != 11; ++i) 
    cout << count_if(words.begin(), words.end(), GT(i))<< " words " << i << " characters or longer" << endl;

3、上面展示给大家的是C++Primer第四版中的实例,有关函数对象的定义看到这里想必大家也已经很清楚了,可是在实际中是怎么用的估计不少人又犯难了。毕竟知道是一回事,而熟练使用则又是另外一回事。

      有可能大家会联想到函数指针,是的,如果你能想到这一步,那么说明你已经有一些功底了。如果还不知道函数指针,请看:函数指针及其应用。函数对象既然是一个“类对象”,那么我们当然可以在函数形参列表中调用它,它完全可以取代函数指针!如果说指针是C的标志,类是C++特有的,那么我们也可以说指针函数和函数对象之间的关系也是同前者一样的!(虽然有些严密)。当我们想在形参列表中调用某个函数时,可以先声明一个具有这种函数功能的函数对象,然后在形参中使用这个对象,他所作的功能和函数指针所作的功能是相同的,而且更加安全。

 

#include <iostream>

using namespace std;

class FuncT{
public:
    template<typename T>
    T operator() (T t1, T t2)
    {
        cout<<t1<<'+'<<t2<<'='<<t1+t2<<endl;
        return t1;
    }
};
template <typename T>
T addFuncT(T t1, T t2, FuncT& funct)
{
    funct(t1,t2);
    return t1;
}

int main()
{
    FuncT funct;
    cout<<addFuncT<int>(2,4,funct)<<endl;
    cout<<addFuncT<double>(1.4,2.3,funct)<<endl;

    return 0;
}
  上面程序运行的结果:


   看到了把,函数对象不仅能够达到函数指针能够达到的目的,并且在应用方面比函数指针更加灵活。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值