C++可调用对象的绑定器和包装器

发布于:2024-04-25 ⋅ 阅读:(124) ⋅ 点赞:(0)

包装器和绑定器

  • 乃神器也
  • 可调用对象、包装器std:function、绑定器std:bind
  • 应用场景:可变函数和参数、回调函数、取代虚函数

可调用对象

在C++中,可以像函数一样调用的有:普通函数、类的静态成员函数、仿函数、lambda函数、类
的成员函数、可被转换为函数的类的对象,统称可调用对象或函数对象。
可调用对象有类型,可以用指针存储它们的地址,可以被引用(类的成员函数除外)

普通函数

普通函数类型可以声明函数、定义函数指针和函数引用,但是,不能定义函数的实体。

#include<algorithm>
#include<iostream>
using namespace std;

using Fun = void(int, const string&);//普通函数类型别名
Fun show;//声明普通函数

//void show(int, const string&);//声明普通函数
int main() {
	show(1, "我是一只小小鸟");//直接调用普通函数
	void(*fp1)(int, const string&) = show;//声明函数指针,指向普通函数
	void(&fr1)(int, const string&) = show;//声明函数指针,引用普通函数
	fp1(2, "我是一只傻傻鸟");//用函数指针调用普通函数
	fr1(3, "我是一只傻傻鸟");//用函数引用调用普通函数
	//下面是C++写法
	Fun* fp2 = show;//声明函数指针,指向普通函数
	Fun& fr2 = show;//声明函数引用,指向普通函数
	fp2(4, "我是一只傻傻鸟");//用函数指针调用普通函数
	fr2(5, "我是一只傻傻鸟");//用函数引用调用普通函数


}
//定义普通函数
void show(int bh, const string& message) {
	cout << "亲爱的" << bh << "," << message << endl;
}
//以下代码是错误的,不能用函数类型定义函数的实体
//Func show1{
//	cout << "亲爱的" << bh << "," << message << endl;
//}

类的静态成员函数

类的静态成员函数和普通函数本质上是一样的,把普通函数放在类中而已。

#include<algorithm>
#include<iostream>
using namespace std;

using Fun = void(int, const string&);//普通函数类型别名
Fun show;//声明普通函数


//void show(int, const string&);//声明普通函数
struct AA {
	static void show(int bh, const string& message) {
		cout << "亲爱的" << bh << "," << message << endl;
	}
};
int main() {
	AA::show(1, "我是一只傻傻鸟。");// 直接调用静态成员函数。
	void(*fp1)(int, const string&) = AA::show; //用函数指针指向静态成员函数。
	void(&fr1)(int, const string&) = AA::show;//引用静态成员函数。
	fp1(2, "我是一只傻傻鸟。");//用函数指针调用静态成员函数。 -
	fr1(3, "我是一只傻傻鸟。");//用函数引用调用静态成员函数。
	Fun * fp2 = AA::show;//用函数指针指向静态成员函数。
	Fun& fr2 = AA::show;//引用静态成员函数。
	fp2(4, "我是一只傻傻鸟。");//用函数指针调用静态成员函数。
	fr2(5, "我是一只傻傻鸟。");//用函数引用调用静态成员函数。



}

仿函数

仿函数的本质是类,调用的代码像函数。
仿函数的类型就是类的类型。

#include<algorithm>
#include<iostream>
using namespace std;

struct BB {//仿函数
	void operator()(int bh, const string& message) {
		cout << "亲爱的" << bh << "," << message << endl;
	}
};
int main() {
	BB bb;
	bb(11, "我是一只傻傻鸟");//用对象调用仿函数
	BB()(12, "我是一只傻傻鸟");//用匿名对象调用仿函数。

	BB& br = bb;//引用函数
	br(13, "我是一只傻傻鸟");//用对象引用调用仿函数

}

lambda函数

lambda函数的本质是仿函数,仿函数的本质是类。

#include<algorithm>
#include<iostream>
using namespace std;

int main() {
	//创建lambda对象
	auto lb = [](int bh, const string& message) {
		cout << "亲爱的" << bh << "," << message << endl;
	};
	auto& lr = lb;
	lb(1, "我是一只傻傻鸟");
	lr(2, "我是一只傻傻鸟");

}

类的非静态成员函数

类的非静态成员函数只有指针类型,没有引用类型,不能引用。
类的非静态成员函数有地址,但是,只能通过类的对象才能调用它,所以,C++对它做了特别处理。
类的非静态成员函数只有指针类型,没有引用类型,不能引用。

#include<algorithm>
#include<iostream>
using namespace std;

struct CC {
	void show(int bh, const string& message) {
		cout << "亲爱的" << bh << "," << message << endl;
	}
};
int main() {
	CC cc;
	cc.show(14, "我是一只傻傻鸟。");
	//void (*fp11)(int, const string&);//这是普通函数指针,多了CC::
	void (CC:: * fp11)(int, const string&) = &CC::show;//定义类的成员函数的指针
	(cc.*fp11)(15, "我是一只傻傻鸟。");///用类的成员函数的指针调用成员函数。


	using pFun = void (CC::*)(int, const string&);//类成员函数的指针类型。
	pFun fp12 = &CC::show;// 让类成员函数的指针指向类的成员函数的地址
	(cc.*fp12)(16, "我是一只傻傻鸟。");//用类成员函数的指针调用类的成员函数。



}

可被转换为函数指针的类对象

类可以重载类型转换运算符operator数据类型(),如果数据类型是函数指针或函数引用类型,那么
该类实例也将成为可调用对象。
它的本质是类,调用的代码像函数。
在实际开发中,意义不大。

包装器function

绑定器bind

可变函数和参数

回溯函数的实现

如何取代虚函数


网站公告

今日签到

点亮在社区的每一天
去签到