可调用对象的概念
//可调用对象:包括一般可以调用的函数, 和 仿函数
//我们之所以学习可调用对象,是为了将 可调用对象的指针 保存起来,方便我们随时调用
//可调用对象:包括一般可以调用的函数, 和 仿函数
//我们之所以学习可调用对象,是为了将 可调用对象的指针 保存起来,方便我们随时调用
//1.一般函数
void func90() {
cout << "func90 一般函数" << endl;
}
int getfunc90(int a ) {
cout << "getfunc90 一般函数 a = " <<a << " return int*2" << endl;
return a * 2;
}
//2.仿函数
class Teacher90 {
public:
// 重载了()号的类: operator() 就是重载(),(int a ) 是参数
void operator()(int a ) {
cout << "仿函数调用 a = " << a << endl;
}
};
void main() {
func90();//一般函数调用
int a = 10;
int b = getfunc90(a); //一般函数调用
cout << b << endl;
//仿函数调用
Teacher90 t;
t(90); //仿函数调用 一个类对象,后边直接小括号,和参数
int c = 100;
t(c);//仿函数调用 一个类对象,后边直接小括号,和参数
}
将可调用对象的指针记录并保存起来
通过函数指针将 一般函数 记录下来
通过 funcation 将 仿函数记录下来。funcation 也可以记录一般函数
//2.仿函数
class Teacher90 {
public:
// 重载了()号的类: operator() 就是重载(),(int a ) 是参数
void operator()(int a ) {
cout << "仿函数调用 a = " << a << endl;
}
};
//3.函数指针
//3.1 回顾C语言的函数指针的定义
typedef int(*FUNZHIZHENTYPE)(int x);// FUNZHIZHENTYPE 是定义的一种类型,这是一种函数指针类型,该函数应该的参数是int,返回值也是int
int(*FUNZHIZHENBIANLIANG)(int x);// FUNZHIZHENBIANLIANG 是函数指针变量,注意:不是类型,是指针变量,可以直接使用呢
//3.2 C++ 中函数指针的定义
function<int(int)> funca; //定义一个 函数指针变量,返回值是void,参数类型是int,变量名字是funca
void main() {
FUNZHIZHENTYPE aaa= getfunc90;//使用函数指针类型,定义一个 函数指针变量 aaa,由于函数名字几就是函数地址,因此可以直接使用 getfunc90
aaa(180);
cout << "-=0-=" << endl;
(*aaa)(180);
cout << "-=0-=" << endl;
funca = getfunc90; //通过function 记录 一般函数,并调用
funca(888);//通过function 记录 一般函数,并调用
cout << "========" << endl;
Teacher90 tt;//通过function 记录 仿函数,并调用
function<void(int)> funcb = tt;//通过function 记录 仿函数,并调用
funcb(999);//通过function 记录 仿函数,并调用
cout << "========" << endl;
通过map保存
//使用map保存 函数指针对象
//一般函数
void fun91(int a ) {
cout << "fun91 call a = " << a << endl;
}
//一般函数
double fun92(string s) {
cout << "fun92 call s = " << s << endl;
return 9.8;
}
class Teacher92 {
public:
//仿函数,重载1
void operator()(int a) {
cout << "operator()(int a) call a = " << a << endl;
}
//仿函数,重载2
double operator()(string s) {
cout << "operator()(string s) call s = " << s << endl;
return 111119.8;
}
};
void main() {
cout << "断点在这里" << endl;
/// 1.是用 C 语言的函数指针保存一般函数的指针
typedef void(*FUNCTYPE)(int);///定义一个 函数指针类型 ,类型名字为 FUNCTYPE,返回值是void,参数是int,
FUNCTYPE aaa = fun91;// 定义一个 函数指针类型的变量 aaa,将func91的地址传递给aaa,由于函数名字就是函数地址,因此可以直接=; 不过由于历史原因,这样写也可以:FUNCTYPE aaa = &fun91;
//调用 aaa(100)
aaa(100);
cout<<""<<endl;
void (*FUNCBIANLIANG)(int); //定义一个 函数指针类型的变量,该变量的名字 就是 FUNCBIANLIANG,返回值是void,参数是int,
FUNCBIANLIANG = fun91;
FUNCBIANLIANG(200);
cout << "" << endl;
double (*funcbianliangdoublestring)(string);
funcbianliangdoublestring = fun92;
double ddd = funcbianliangdoublestring("sss");
cout << "" << " ddd = " << ddd << endl;
/// 2.但是仿函数没有办法使用 C 语言的函数指针保存。要是用C++的 function 保存,头文件为<functional>
Teacher92 t92;
function<void(int)> fanghanshu1 = t92;
fanghanshu1(10);
function<double(string)> fanghanshu2 = t92;
fanghanshu2("nihao");
//3.使用map 将这些函数指针 保存起来
map<int, function<double(string)>> map1;
map1.insert({ 1, fanghanshu2 });
map1.insert({ 2, funcbianliangdoublestring });
//map1.insert({ 3, FUNCBIANLIANG });//build error , FUNCBIANLIANG 是 void(*)(int)
//map1.insert({ 4, aaa });//build error , FUNCBIANLIANG 是 void(*)(int)
map<int, void(*)(int)> map2;
map2.insert({1,aaa});
map2.insert({ 2,FUNCBIANLIANG });
//map2.insert({ 3,fanghanshu1 });//fanghanshu1 类型是符合的,但是是function的,map2是 void(*)(int)的,无法兼容 function<void(int)>
map<int, function<void(int)>> map3;
map3.insert({1,aaa});
map3.insert({ 2,FUNCBIANLIANG });
map3.insert({ 3,fanghanshu1 });//这样就可以,mp3是 function的,只要是参数和返回值符合的,不管是 function 或者 C 的 void(*)(int),都能符合要求
cout << "==--0099--==" << endl;
//调用
map3[2](989);
}
另外的知识点:
如果函数有重载,则不能直接放在 function 里面,我们可以通过定义函数指针来解决.
//fun93有重载1
int fun93() {
cout << "fun93 call " << endl;
return 100;
}
//fun93有重载2
int fun93(int a) {
cout << "fun93 call a = " <<a << endl;
return a + 100;
}
void main() {
function<double(string)> fff0 = fun92; // fun92没有重载,可以直接放在 function后
//function<int(int)> fff1 = fun93; // build error :原因:fun93有重载,因此不能直接将fun93
//解决方案:定义一个函数指针变量,来接受不同参数的fun93函数
int(*fp1)(int) = fun93;
int(*fp2)() = fun93;
function<int(int)> fff2 = fp1; //这样就能存储在 map<string, function<int(int)>>中了
fff2(898888);
int ee = fff2(120);
cout << "ee = " << ee << endl;
}