调用操作符的重载与函数对象

一:调用操作符重载:我们可以为类类型的对象重载调用操作符即小括弧”()“,定义了调用操作符的类,在使用定义的调用操作符时,行为就像是调用函数,所以这种对象称为函数对象,即行为类似函数的对象:

如下例子为类A定义了调用操作符,功能是返回一个绝对值:

class A

{

  public:

    int operator() (int val)

    {

      return val < 0 ? -val : val;

    }

};

调用操作符使用以下两种方法都可以:

A a;

int n = a.operator()(-1);

int n = a(-1); //使用方式像是调用了一个函数

调用操作符可以重载多个版本,通过函数形参的类型及数目区分,如再为类A重载一个形参类型为char *的调用操作符函数:

void operator(char *p)

{

    *p = '\0';

}

使用以上调用操作符:

char arr[] = "ABC";

char *pa = arr;

a.operator()(pa);

a(pa);

二:函数对象用于标准库算法:

a:例如查找比指定值大的数,可以先定义一个类B,为其定义调用操作符,使用该类的对象实现查找:

class B

{

  public:

    B(int val = 0) : ival(val) {} //构造函数初始化成员 ival;

    bool operator()(const int &v)

    {

      return v > ival;  //返回真值,如果传递进来的实参大于成员ival,ival在调用构造函数时被初始化;

    }

  private:

    int ival;

};

用标准库算法find_if进行查找,比如查找大于10的数:

int b[] = {1, 52, 12, 30, 9, 19};

vector<int> ivec(b, b+6);

 vector<int>::iterator ite = ivec.begin();
  while((ite = find_if(ite, ivec.end(), B(10))) != ivec.end())
  {
    cout << *ite << " ";
    ite++;
  }

find_if函数的第三个参数是一个接受一个参数并返回bool型的函数,在这里我们可以传递给find_if算法函数一个类类型B的临时对象,通过传递值10给构造函数初始成员ival,现在find_if每次调用它的函数形参时,依次将vector中的每个元素都应用类B的调用操作符,然后该操作符根据成员ival的值,对传进的实参即vector的每个元素进行比较,如果函数对象返回为真,则find_if返回指向该元素的迭代器;


b:统计大于指定值的次数,以上述代码为基础:

int n = count_if(ivec.begin(), ivec.end(), B(10));

同样,count_if以函数调用的方式调用类B调用操作符,对vector中每个元素进行比较,如果为真,则计数器加1,知道vector的末端元素;

全部代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class A
{
  public:
    int operator() (int val)
    {
      return val > 0 ? val : -val;
    }

    void operator() (char *p)
    {
      *p = 'B';
    }
};

class B
{
  public:
    B(int val = 0) : ival(val) {} //构造函数初始化成员 ival;
    bool operator()(const int &v)
    {
      return v > ival;  //返回真值,如果传递进来的实参大于成员ival,ival在调用构造函数时被初始化;
    }

  private:
    int ival;
};

int main()
{
  int i = -42;
  A  a;
  unsigned int ui = a(i);
 // unsigned int ui = a.operator()(i);
  cout << ui << endl;
  char arr[] = "ABC";
  char *pa = arr;
  a(pa);
  //a.operator()(pa);
  cout << pa << endl;

  int b[] = {1, 52, 12, 30, 9, 19};
  vector<int> ivec(b, b+6);
  vector<int>::iterator ite = ivec.begin();
  while((ite = find_if(ite, ivec.end(), B(10))) != ivec.end())
  {
    cout << *ite << " ";
    ite++;
  }
  cout << endl;

  int n = count_if(ivec.begin(), ivec.end(), B(10));
  cout << "n:" << n << endl;

  return 0;
}

运行结果:

42
BBC
52 12 30 19
n:4
上述代码g++编译通过!



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

种菜的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值