32 C++ 可调用对象,仿函数 ,functional类型,

可调用对象的概念

//可调用对象:包括一般可以调用的函数, 和 仿函数


//我们之所以学习可调用对象,是为了将 可调用对象的指针 保存起来,方便我们随时调用

//可调用对象:包括一般可以调用的函数, 和 仿函数
//我们之所以学习可调用对象,是为了将 可调用对象的指针 保存起来,方便我们随时调用

//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;
}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值