仿函数与谓词
谓词一
谓词 约等于 仿函数 (C++ 中仿函数才是正常说法,谓词是专业术语)
仿函数 == 谓词
#include <iostream>
#include <set> // STL包
#include <algorithm> //算法包
using namespace std;
//为什么叫仿函数 (空谓词 没有参数一元谓词 同理,二元三元就是加多一个方法的参数)
class ComPareObject{
public:
void operator()(){//重载了括号运算符
cout << "仿函数" << endl;}
};
//普通函数
void fun2(){
cout << "普通函数" << endl;
}
int main(){
ComPareObject fun1;
// 非常像函数的调用
fun1();
fun2();
return 0;
}
谓词二
这是系统源码中for_each,我们来学习仿照它的写法
#include <iostream>
#include <set> // STL包
#include <algorithm> //算法包
using namespace std;
// 如何阅读C++源码,来写我们的仿函数
class showActionObj{
pbulic:
int count = 0;
// __f(*__first)
// *__first:是int类型 __f: 没有返回值
void operator()(int content){
cout << "自定义仿函数" << content << endl;
count++;
}
void _count(){
count << "本次输出的次数是:" << this->count << endl;
}
};
// 简洁方式(回调函数 但是不能称为仿函数),扩展性不高,需求复杂的时候很难满足
void showAction(int content) {
cout << "自定义 一元谓词" << content << endl;
}
int main(){
set<int> setVar;
setVar.insert(10);
setVar.insert(20);
setVar.insert(30);
setVar.insert(40);
setVar.insert(50);
setVar.insert(60);
// 输出 10 20 30 40 50 60
showActionObj s;
s = for_each(setVar.begin(), setVar.end(), s);
s._count();
// showAction 回调函数,不用加括号
for_each(setVar.begin(), setVar.end(), showAction);
return 0;
}
学习系统仿函数
#include <iostream>
#include <set> // STL包
#include <algorithm> //算法包
using namespace std;
// C++源码: typename _Compare = std::less less内置的仿函数,根据它来写自定义
// bool operator()(const _Tp& __x, const _Tp& __y) const 二元谓词
class CompareObjectClass{
public:
bool operator() (const _Tp& __x, const _Tp& __y) const {
//把系统的源码复制过来,修改了一个 > 变成 <
return __x < __y;
}
};
int main(){
set<string, CompareObjectClass> setVar;
setVar.insert("aaaa");
setVar.insert("bbbb");
setVar.insert("cccc");
setVar.insert("dddd");
setVar.insert("eeee");
setVar.insert("ffff");
//使用系统默认的 从a到f 使用自己定义的因为反过来,从f到a
for(set<string>::iterator it = setVar.begin(); it != setVar.end();it++){
cout << "循环item" << *it << endl;
}
return 0;
}
对象存入容器生命周期
#include <iostream>
#include <set> // 存入对象 崩溃(set会自动排序,对象没法排序所以崩溃),自定义仿函数
#include <vector> // 存入对象
class Person{
private:
string name;
public:
Person(string name) : name(name) {}
void setName(string name) {
this->name = name;
}
void getName(){
return this->name;
}
Person(const Person & p){
this->name = name;// 浅拷贝
cout << "Person拷贝构造函数执行了" << endl;
}
~Person(){
cout << "Person析构函数执行了" << endl;
}
};
int main(){
// java: 把对象存入 添加到集合中
//C++:调用拷贝构造函数,存进去的是另一个新的对象
vector<Person> vectorVar;
Person person("aaa");//被main函数弹栈的话肯定会执行析构函数一次
//里面的insert函数弹栈析构一次
vectorVar.insert(vectorVar.begin(),person);//执行拷贝构造函数一次
person.setName("bbb");
// front里面的person是旧地址,外面的newPerson就是新地址 执行拷贝构造函数一次
//newPerson 被main函数弹栈 析构一次
Person newPerson = vectorVar.front();
cout << "newPerson" << newPerson.getName().c_str() << endl;//输出aaa
// 3次析构函数 2次构造函数
return 0;
}
预定义函数
#include <iostream>
#include <set> //STL包
#include <algorithm> //算法包
int amin(){
// “aaaa” + “bbbb”
// C++已经提供了 预定义函数
plus<int> add_func;
int r = add_func(1,1);// r = 2
plus<string> add_func2;
int r = add_func2("a","b");// r = ab
return 0;
}