目录
🤔函数对象:
🤔本质:
🤔特点:
代码示例:
运行结果:
🤔 内置函数对象:
1.算数仿函数
代码示例:
运行结果:
2.关系仿函数
代码示例:
运行结果:
3.逻辑仿函数:
代码示例:
运行结果:
🤔结束!
🤔函数对象:
📖用类创建出来的一个对象,调用起来语法结构像调用函数,我们把这种对象叫做函数对象。它通过重载函数调用操作符(operator())来实现可调用操作。可以将函数对象看作是一种可调用的“函数”,它可以封装一组函数调用所需要的状态和行为。函数对象可以像普通函数一样被调用,也可以像普通对象一样被拷贝、赋值、作为参数传递给其他函数等。函数对象广泛地应用于STL算法中,例如排序和查找等操作。函数对象可以使程序更加灵活和高效,因为它可以在运行时自定义函数的行为。
📖而函数对象的重点在于学会使用C++提供给我们的内置函数对象。
🤔本质:
📖 本质是一个对象。
🤔特点:
📖1.函数对象在使用的时候,可以像普通的函数那样调用,可以有参数,可以有返回值
📖2.函数对象超出普通函数的概念,可以有自己的状态
📖3.函数对象可以作为参数传递
代码示例:
#include<iostream>
using namespace std;
class myhanshu
{
public:
myhanshu()
{
this->count = 0;
}
int operator()(int v1,int v2)
{
return v1 + v2;
}
void operator()(string name)
{
cout << name<<endl;
count++;
}
int count;
};
void dowork(myhanshu d, string words)
{
d(words);
}
void test01()
{
//创建一个函数对象
myhanshu MYadd;
//1.函数对象在使用的时候可以像普通的函数那样调用,可以有自己的参数,可以有返回值
cout<<MYadd(3, 4)<<endl;
//函数对象超出普通函数的概念,可以有自己的状态,例如我们可以通过内置成员count统计
myprintf调用次数。
myhanshu myprintf;
myprintf("hello world");
myprintf("hello world");
myprintf("hello world");
myprintf("hello world");
cout<<"myprintf函数一共调用了" << myprintf.count<<"次" << endl;
//类可以作为参数传递
dowork(myprintf, "wo ai c++");
}
int main()
{
test01();
}
运行结果:
🤔 内置函数对象:
1.算数仿函数
提供运算模板供我们使用
📖1.template<class T> T plus<T> 加法仿函数
📖2.template<class T> T minus<T> 减法仿函数
📖3.template<class T> T multiplies<T> 乘法仿函数
📖4.template<class T> T divides<T> 除法仿函数
📖5.template<class T> T modulus<T> 取模仿函数
📖6.template<class T> T negate<T> 取反仿函数
这里我们只简单举两个例子,其余用法都一致
代码示例:
#include<iostream>
using namespace std;
#include<functional>
void test01()
{
plus<int>n;//加法仿函数
cout<<"50+40=" << n(50, 40)<<endl;
negate<int>c;//取反仿函数
cout << "-90的取反结果为" << c(-90);
}
int main()
{
test01();
}
运行结果:
2.关系仿函数
📖1.template<class T> bool equal_to<T> 等于仿函数
📖2.template<class T> bool not_equal_to<T> 不等于仿函数
📖3.template<class T> bool greater<T> 大于
📖4.template<class T> bool greater_equal<T> 大于等于仿函数
📖5.template<class T> bool less<T> 小于仿函数
📖6.template<class T> bool less_equal<T> 等于仿函数
此类仿函数常用于sort排序函数中,一般情况下我们要自定义排序就需要自己写排序规则,而如果关系仿函数满足我们的需求的话,我们直接调用关系仿函数就好了。
代码示例:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void printv(vector<int >& v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
vector<int> v1;
v1.push_back(123);
v1.push_back(232);
v1.push_back(33);
v1.push_back(54);
printv(v1);
sort(v1.begin(), v1.end(), greater<int>());
printv(v1);
}
运行结果:
其实sort函数默认的由大到小排序也是在用仿函数less达到的。
3.逻辑仿函数:
📖1. template<class T> bool logical_and<T> 逻辑与
📖2.template<class T> bool logical_or<T> 逻辑或
📖3. template<class T> bool logical_not<T> 逻辑非
逻辑仿函数属于冷门仿函数,用处比较少。
我们用一个案例来说明:要求对一个vector容器中的元素进行更换容器以及取反操作
代码示例:
#include<iostream>
using namespace std;
#include<functional>
#include<vector>
#include<algorithm>
void printv(vector<bool >& v)
{
for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
vector<bool> d1;
d1.push_back(true);
d1.push_back(false);
d1.push_back(true);
d1.push_back(false);
d1.push_back(true);
printv(d1);
//我们采用逻辑运算符 逻辑非实现对vector容器中的数值取反
vector<bool> d2;
d2.resize(d1.size());
transform(d1.begin(), d1.end(),d2.begin(), logical_not<bool>());
printv(d2);
}
int main()
{
test01();
}