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

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

        分类:            c/c++ 111人阅读 评论(1) 收藏 举报

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

如下例子为类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的末端元素;

全部代码:

  1. #include <iostream> 
  2. #include <vector> 
  3. #include <algorithm> 
  4.  
  5. using namespace std; 
  6.  
  7. class A 
  8.   public: 
  9.     int operator() (int val) 
  10.     { 
  11.       return val > 0 ? val : -val; 
  12.     } 
  13.  
  14.     void operator() (char *p) 
  15.     { 
  16.       *p = 'B'
  17.     } 
  18. }; 
  19.  
  20. class B 
  21.   public: 
  22.     B(int val = 0) : ival(val) {} //构造函数初始化成员 ival; 
  23.     bool operator()(const int &v) 
  24.     { 
  25.       return v > ival;  //返回真值,如果传递进来的实参大于成员ival,ival在调用构造函数时被初始化; 
  26.     } 
  27.  
  28.   private: 
  29.     int ival; 
  30. }; 
  31.  
  32. int main() 
  33.   int i = -42; 
  34.   A  a; 
  35.   unsigned int ui = a(i); 
  36. // unsigned int ui = a.operator()(i); 
  37.   cout << ui << endl
  38.   char arr[] = "ABC"; 
  39.   char *pa = arr
  40.   a(pa); 
  41.   //a.operator()(pa); 
  42.   cout << pa << endl
  43.  
  44.   int b[] = {1, 52, 12, 30, 9, 19}; 
  45.   vector<int> ivec(b, b+6); 
  46.   vector<int>::iterator ite = ivec.begin(); 
  47.   while((ite = find_if(ite, ivec.end(), B(10))) != ivec.end()) 
  48.   { 
  49.     cout << *ite << " "; 
  50.     ite++; 
  51.   } 
  52.   cout << endl
  53.  
  54.   int n = count_if(ivec.begin(), ivec.end(), B(10)); 
  55.   cout << "n:" << n << endl
  56.  
  57.   return 0; 
#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
上述代码gcc编译通过!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值