调用操作符的重载与函数对象
2016-06-14 15:57
375 查看
一:调用操作符重载:我们可以为类类型的对象重载调用操作符即小括弧”()“,定义了调用操作符的类,在使用定义的调用操作符时,行为就像是调用函数,所以这种对象称为函数对象,即行为类似函数的对象:
如下例子为类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的末端元素;
全部代码:
[html] view
plain copy
print?
#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++编译通过!
如下例子为类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的末端元素;
全部代码:
[html] view
plain copy
print?
#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++编译通过!
相关文章推荐
- iOS Provisioning Profile(Certificate)与Code Signing详解
- Android多线程—–AsyncTask详解
- BZOJ2789: [Poi2012]Letters
- 组合模式
- centos6.5安装jira6.3.6详细文档汉化破解
- 后记:IT软件人员学习的书籍 - IT软件人员书籍系列文章
- 使用httplib打开链接
- 【shell】通配符
- S2-033漏洞分析
- USB主机控制器(Host Controller)--深入理解
- 使用C#格式化字符串
- 思科无线AP配置之一(使用超级终端连接设备篇)
- 如何借助 HealthKit 打造一款健身应用?
- mysql主从复制实践之单数据库多实例
- android图片压缩,注释很详细
- STL之deque容器详解
- IP地址与无符号整形互转
- Dapper.Net 应用
- ASP.NET Redis 开发(转载)
- com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed J