函数对象
概念:
重载函数调用操作符的类,其对象称为函数对象。
函数对象使用重载的()时,行为类似函数调用,也叫仿函数。
本质:
函数对象(仿函数)是一个类,不是一个函数。
特点:
1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值。
2、函数对象超出普通函数的概念,函数对象可以有自己的状态。
3、函数对象可以作为参数传递。
函数对象本质是一个类,重载了函数调用运算符() ‘operator()’,使对象可以像函数一样被调用,并且通常用于在算法中提供自定义的行为。
函数对象相比普通函数可以携带状态(通过成员变量),并且函数对象可以作为模板参数传递,普通函数都不可以。
案例代码:
class MyAdd
{
public:
int operator()(int num1,int num2) // 特点1
{
return (num1 + num2);
}
};
class MyPrint
{
public:
int count; // 内部状态
MyPrint()
{
this->count = 0;
}
void operator()(string text) // 特点2
{
cout << "text = " << text << endl;
count++;
}
};
void doPrint(MyPrint &myPrint,string text) // 特点3
{
myPrint(text);
}
int main()
{
MyAdd myAdd;
cout << myAdd(10, 20) << endl;
MyPrint myPrint;
myPrint("hello world");
myPrint("hello world");
myPrint("hello world");
cout << "myPrint对象调用仿函数次数 = " << myPrint.count << endl;
doPrint(myPrint,"doPrint(),hello world");
system("pause");
return 0;
}
输出结果:
谓词
- 返回bool类型的仿函数称为谓词。
- 如果operator()接收一个参数,叫做一元谓词。接收两个参数叫做二元谓词。
一元谓词:
案例代码:
#include <vector>
#include <algorithm>
class GreaterFive
{
public:
bool operator()(int val)
{
return (val > 5);
}
};
void test()
{
vector<int> v;
for (int i = 0; i < 10; i++)
v.push_back(i + 1);
// 查找大于5的数
// GreaterFive()为匿名函数对象,这是简化写法 也可以直接传入GreaterFive类的对象
vector<int>::iterator it = find_if(v.begin(),v.end(), GreaterFive());
if (it != v.end())
cout << "找到了,该数字为:" << *it << endl;
else
cout << "未找到" << endl;
}
int main()
{
test();
system("pause");
return 0;
}
输出结果:
二元谓词:
案例代码:
#include <vector>
#include <algorithm>
class MyCompare
{
public:
bool operator()(int n1, int n2) // 自定义降序排序
{
return (n1 > n2);
}
};
void printVector(const vector<int> &v)
{
for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
cout << *it << "\t";
cout << endl;
}
void test()
{
vector<int> v;
v.push_back(30);
v.push_back(20);
v.push_back(10);
v.push_back(40);
printVector(v);
cout << "sort默认排序方式:" << endl;
sort(v.begin(),v.end()); // 默认升序排序
printVector(v);
cout << "自定义降序排序:" << endl;
sort(v.begin(), v.end(),MyCompare()); // 匿名函数对象
printVector(v);
}
int main()
{
test();
system("pause");
return 0;
}
输出结果:
内建函数对象
STL内建了一些函数对象。
分类:算数仿函数、关系仿函数、逻辑仿函数。
用法:
这些仿函数所产生的对象,用法和一般函数完全相同。
使用内建函数对象,需要引入头文件 #include < functional >。
内建函数对象-算数仿函数:
功能描述:
实现四则运算,其中negate是一元运算,其他都是二元运算。
template< class T > T plus< T > // 加法仿函数
template< class T > T minus< T > // 减法仿函数
template< class T > T multiplies< T > // 乘法仿函数
template< class T > T divides< T > // 除法仿函数
template< class T > T modulus< T > // 取模仿函数
template< class T > T negate< T > // 取反仿函数
案例代码:
#include <functional>
void test01()
{
negate<int> n;
cout << "50取反 = " << n(50) << endl;
modulus<int> m;
cout << "50 % 6 = " << m(50, 6) << endl;
}
void test02()
{
plus<int> p;
cout << "10 + 20 = " << p(10, 20) << endl;
minus<int> m;
cout << "20 - 10 = " << m(20, 10) << endl;
multiplies<int> m2;
cout << "20 * 10 = " << m2(20, 10) << endl;
divides<int> m3;
cout << "20 / 10 = " << m3(20, 10) << endl;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
输出结果:
内建函数对象-关系仿函数:
template< class T > bool equal_to< T > // 等于
template< class T > bool not_equal_to< T > // 不等于
template< class T > bool greater< T > // 大于
template< class T > bool greater_equal< T > // 大于等于
template< class T > bool less< T > // 小于
template< class T > bool less_equal< T > // 小于等于
案例代码:
#include <vector>
#include <algorithm>
#include <functional>
class MyCompare
{
public:
bool operator()(int val1, int val2)
{
return (val1 > val2);
}
};
void printVector(const vector<int>& v)
{
for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
cout << *it << "\t";
cout << endl;
}
void test()
{
vector<int> v;
v.push_back(30);
v.push_back(10);
v.push_back(20);
v.push_back(40);
printVector(v);
cout << "排序后:" << endl;
//sort(v.begin(),v.end(),MyCompare()); // 自己实现的仿函数
sort(v.begin(),v.end(),greater<int>()); // STL内建仿函数,大于仿函数
printVector(v);
}
void test02()
{
int val1 = 10, val2 = 20;
not_equal_to<int> net;
cout << net(val1,val2) << endl; // 非0即为真
cout << not_equal_to<int>()(val1, val2) << endl; // 匿名函数对象在调用时构造输出,结果与上行代码一致
}
int main()
{
test();
test02();
system("pause");
return 0;
}
输出结果:
内建函数对象-逻辑仿函数:
template< class T > bool logical_and< T > // 逻辑与
template< class T > bool logical_or< T > // 逻辑或
template< class T > bool logical_not< T > // 逻辑非
案例代码:
#include <vector>
#include <algorithm>
#include <functional>
void printVector(const vector<bool> &v)
{
for (vector<bool>::const_iterator it = v.begin(); it != v.end(); it++)
cout << *it << "\t";
cout << endl;
}
void test()
{
vector<bool> v;
v.push_back(true);
v.push_back(true);
v.push_back(false);
v.push_back(true);
v.push_back(false);
printVector(v);
// 利用内建STL 逻辑非,将容器v的元素搬运到v2容器中并将元素进行取反操作
vector<bool> v2; // 存放取反数据的容器
v2.resize(v.size()); // 指定取反容器大小
transform(v.begin(),v.end(),v2.begin(),logical_not<bool>()); // 搬运函数,后期讲解
cout << "取反后:" << endl;
printVector(v2);
}
int main()
{
test();
system("pause");
return 0;
}
输出结果: