四网合一网站建设,wordpress批量添加摘要,优秀的广告设计作品,三只松鼠网络营销方案可调用对象在C中#xff0c;可以像函数一样调用的有#xff1a;普通函数、类的静态成员函数、仿函数、lambda函数、类的非静态成员函数、可被转换为函数的类的对象#xff0c;统称可调用对象或函数对象。可调用对象有类型#xff0c;可以用指针存储它们的地址#xff0c;可…可调用对象在C中可以像函数一样调用的有普通函数、类的静态成员函数、仿函数、lambda函数、类的非静态成员函数、可被转换为函数的类的对象统称可调用对象或函数对象。可调用对象有类型可以用指针存储它们的地址可以被引用类的成员函数除外。这里举几个例子仿函数本质是重载了()的类#includeiostream
using namespace std;
struct Object
{void operator()(int age, string name){cout 年龄 age 姓名 name endl;}
};
int main()
{Object obj;obj(20, 小谢);Object obj_r obj; // 引用函数obj_r(19, 小赵);return 0;
}lambda函数#includeiostream
using namespace std;
int main()
{auto func [](int age, string name){cout 年龄 age 姓名 name endl;};func(20, 小谢);auto func_r func;// 引用lambda对象。func_r(19, 小赵);return 0;
}类的非静态成员函数类的非静态成员函数有地址但是只能通过类的对象才能调用它所以C对它做了特别处理。类的非静态成员函数只有指针类型没有引用类型不能引用。#includeiostream
using namespace std;
struct Object
{void show(int age, string name){cout 年龄 age 姓名 name endl;}
};
int main()
{Object obj;obj.show(20, 小谢);void(Object::*pobj)(int, string) Object::show;// 定义类的成员函数的指针。(obj.*pobj)(19, 小赵);using PFun void(Object::*)(int, string);PFun p_show Object::show;(obj.*p_show)(18, 芜湖);return 0;
}在上面的例子中满足条件的这些可调用对象对应的类型被统称为可调用类型。C 中的可调用类型虽然具有比较统一的操作形式但定义方式五花八门这样在我们试图使用统一的方式保存或者传递一个可调用对象时会十分繁琐。现在C11通过提供std::function 和 std::bind统一了可调用对象的各种操作。包装器function包含头文件#include functionalstd::function返回值类型(参数类型列表) diy_name 可调用对象;#includeiostream
#includefunctional
using namespace std;
int add(int a, int b)
{cout a b a b endl;return a b;
}
class T
{
public:static int sub(int a, int b){cout a * b a * b endl;return a * b;}
};
class T1
{
public:int operator()(int a, int b){cout a - b a - b endl;return a - b;}
};
int main()
{//std::function返回值类型(参数类型列表) diy_name 可调用对象;functionint(int, int) f1 add;f1(1, 2);functionint(int, int) f2 T::sub;f2(2, 3);T1 t;functionint(int, int) f3 t;f3(3, 4);return 0;
}通过测试代码可以得到结论std::function 可以将可调用对象进行包装得到一个统一的格式包装完成得到的对象相当于一个函数指针和函数指针的使用方式相同通过包装器对象就可以完成对包装的函数的调用了。作为回调函数使用#include iostream
#include functional
using namespace std;
class A
{
public:// 构造函数参数是一个包装器对象A(const functionvoid() f) : callback(f){}void notify(){callback(); // 调用通过构造函数得到的函数指针}
private:functionvoid() callback; //成员变量-包装器对象
};class B
{
public:void operator()(){cout !!! endl;}
};
int main(void)
{B b;A a(b);a.notify();return 0;
}
绑定器bindstd::bind()模板函数是一个通用的函数适配器绑定器它用一个可调用对象及其参数生成一个新的可调用对象以适应模板。函数原型template class Fx, class... Args function bind (Fx fx, Args...args);
Fx需要绑定的可调用对象
args/*绑定参数列表可以是左值、右值和参数占位符std::placeholders::_n如果参数不是占位符缺省为值传递std:: ref(参数)则为引用传递。*/std::bind()返回std::function的对象。std::bind()的本质是仿函数。// 绑定非类成员函数/变量auto f std::bind(可调用对象地址, 绑定的参数/占位符);// 绑定类成员函/变量auto f std::bind(类函数/成员地址, 类实例对象地址, 绑定的参数/占位符); 类成员函数需要绑定该类的this指针 。#includeiostream
#includefunctional
using namespace std;
struct Object
{void operator()(int age, string name){cout 年龄 age 姓名 name endl;}void show(int age, string name){cout 年龄 age 姓名 name endl;}};
int main()
{Object obj;functionvoid(int, string) f1 bind(Object(), placeholders::_1, placeholders::_2);f1(20, 小谢);auto func [](int age, string name){cout 年龄 age 姓名 name endl;};functionvoid(int, string) f2 bind(func, placeholders::_1, placeholders::_2);f2(19, 小赵);// 类成员函数需要绑定该类的this指针 Object obj1;functionvoid(Object, int, string) f3 bind(Object::show, placeholders::_1, placeholders::_2, placeholders::_3);f3(obj1,17,张三);//这里为了统一将对象提前绑定functionvoid(int, string) f4 bind(Object::show, obj1, placeholders::_1, placeholders::_2);f4(16, 李四);return 0;
}在用绑定器绑定类成员函数或者成员变量的时候需要将它们所属的实例对象一并传递到绑定器函数内部。bind的应用改变参数位置例如函数需要一个int和string两个参数auto f bind(func, placeholders::_1, placeholders::_2);第一个参数为int第二个为string但是如果第一个想第一个传入string第二个传入intauto f bind(func, placeholders::_2, placeholders::_1);改变参数个数改变参数个数主要是为了统一便于使用函数模板例如上述例子的部分代码Object obj1;
functionvoid(Object, int, string) f3 bind(Object::show, placeholders::_1, placeholders::_2, placeholders::_3);
f3(obj1,17,张三);
//这里为了统一将对象提前绑定
functionvoid(int, string) f4 bind(Object::show, obj1, placeholders::_1, placeholders::_2);
f4(16, 李四);这里采取的是提前绑定将对象提前绑定。设置类成员函数为回调函数在讲bind时上面已演示