- 一. 函数对象概念
- 二. 一元谓词
- 三. 二元谓词
- 四. 内建函数对象
- ① 概念
- ② 分类
- ③ 用法
- ④ 算术仿函数
- ⑤ 关系仿函数
- ⑥ 逻辑运算仿函数
概念:
- 重载函数调用 *** 作符的类,其对象常称为函数对象.
- 函数对象使用重载的()时,行为类似函数的调用,所以也叫仿函数
本质:
函数对象(仿函数)是一个类,不是一个函数
特点:
- 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
- 函数对象超出了普通的函数的概念,函数对象可以有自己的状态(类属性)
- 函数对象可以作为参数传递
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include
using namespace std;
// 函数对象在使用的时候,可以像普通函数那样调用,可以有参数,可以有返回值
class MyAdd
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
void test_01(void)
{
// 创建一个函数对象
MyAdd add;
int a = 10;
int b = 20;
// add(a,b) 类似于函数的调用,但是本质上不是函数的调用,是一个 *** 作符的重载,也就是仿函数
cout << a << " + " << b << " = " << add(a, b) << endl;
}
// 仿函数可以有自己的状态(类属性)
class MyPrint
{
public:
MyPrint()
{
mCount = 0;
}
void operator()(string text)
{
cout << text << endl;
mCount++;
}
int mCount; // 函数调用次数
};
void test_02(void)
{
MyPrint print;
print("Fioman");
print("Fioman");
print("Fioman");
print("Fioman");
cout << "调用次数: " << print.mCount << endl;
}
void do_print(MyPrint mp, string text)
{
mp(text);
}
// 可以作为函数的参数
void test_03(void)
{
MyPrint print;
do_print(print, "Hello World!");
}
int main()
{
test_01();
test_02();
test_03();
system("pause");
return 0;
}
二. 一元谓词
谓词的概念:
- 返回
bool
类型的仿函数称为谓词- 如果
operator()
接收一个参数,那么叫做一元谓词- 如果
operator()
接收两个参数,那么叫做二元谓词
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include
using namespace std;
#include
#include
class GreaterFive
{
public:
// 创建一元谓词,返回值要是bool类型,并且参数只有一个
bool operator()(int a)
{
return a > 5;
}
};
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
// GreaterFive()是一个匿名变量
// 也是一个一元谓词. find_if的返回值是一个迭代器
// 如果找到了,返回这个元素的位置,如果没有找到,就返回end();
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
if (it != v.end())
{
cout << "找到了,找到的元素: " << *it << endl;
}
else
{
cout << "没有找到大于5的元素" << endl;
}
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
形参有两个参数的谓词称为二元谓词
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include
using namespace std;
#include
#include
// 二元谓词
class MyCompare
{
public:
bool operator()(int a,int b)
{
return a > b;
}
};
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(rand()% 10);
}
// 默认的排序算法,从小到大进行排序
sort(v.begin(), v.end());
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
// 使用二元谓词改变排序规则,从大到小
cout << "------------------------------" << endl;
sort(v.begin(), v.end(), MyCompare());
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
四. 内建函数对象
① 概念
② 分类STL内建了一些函数对象
③ 用法
- 算术仿函数(函数对象)
- 关系仿函数(函数对象)
- 逻辑仿函数(函数对象)
④ 算术仿函数
- 这些仿函数所产生的对象,用法和一般函数完全相同
- 使用内建函数对象,需要引入头文件
#include
功能:
- 实现四则运算
- 其中negate是一元运算,其他都是二元运算
仿函数原型
template
// 加法仿函数T plus template
// 减法仿函数T minus template
// 乘法仿函数T multiplies template
// 除法仿函数T divides template
// 取模仿函数T modulus
6)template
// 取反仿函数,正负号取反T negate
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include
using namespace std;
#include
// 内建仿函数 算术仿函数
// negate
void test_01(void)
{
// 取反
negate<int> n;
cout << n(50) << endl;
// 加,只有一个参数类型,因为只允许同种类型的才可以相加
plus<int> p;
cout << p(10, 20) << endl;
// 减
minus<int> m;
cout << m(10, 20) << endl;
// 乘
multiplies<int> mul;
cout << mul(10, 20) << endl;
// 除
divides<int> div;
cout << div(10, 20) << endl;
// 取模
modulus<int> mod;
cout << mod(10, 20) << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
⑤ 关系仿函数
函数原型:
template
// 等于bool equal_to template
// 不等于bool not_equal_to template
// 大于bool greater template
// 大于等于bool greater_equal template
// 小于bool less template
// 小于等于bool less_equal
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include
using namespace std;
#include
#include
#include
void test_01(void)
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);
// 默认排序,从小到大
sort(v.begin(), v.end());
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
// 使用内建的函数,从大到小金星排序
sort(v.begin(), v.end(), greater<int>());
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
⑥ 逻辑运算仿函数
原型:
template
// 逻辑与bool logical_and
2)template
// 逻辑或bool logical_or
3)template
// 逻辑非bool logical_not
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include
using namespace std;
#include
#include
#include
void test_01(void)
{
vector<bool> v;
v.push_back(true);
v.push_back(false);
v.push_back(true);
v.push_back(false);
for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
// 利用逻辑非 将容器v搬运到容器v2中,并执行取反 *** 作
vector<bool> v2;
v2.resize(v.size());
transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)