扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
平时编程时,多用来将数据进行传参,在考虑回调场景下我们会将函数单做参数传给被调用函数,让被调用函数在时机成熟时进行调用。在某些场景下,需要将类的成员函数当作参数进行回调,此时定义成员函数形参的方式通常有两种,以一种是成员函数指针类型,另外一种是使用std::function函数包装器。
目前成都创新互联公司已为千余家的企业提供了网站建设、域名、虚拟主机、网站托管运营、企业网站设计、遂昌网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。目录
1. C++常见的可调用对象
(1) 普通函数
(2) lambda表达式
(3) 函数对象类
(4) 类的静态成员函数
(5) 类的普通成员函数
2. 成员函数指针当作形参调用成员函数
3. std::function作为形参调用成员函数
int MyAdd(int num1, int num2){ return num1+num2; }
(2) lambda表达式auto MyMod = [](int num1, int num2){ return num1%num2; };
(3) 函数对象类struct MyDivide{
int operator()(int num1, int num2){
return num1/num2;
}
};
(4) 类的静态成员函数class MyMul {
public:
static int mul(int num1, int num2) {
return num1*num2;
}
};
(5) 类的普通成员函数class MyClass {
public:
void show(const int &num1 = 100, const int &num2 = 300) {
std::cout<< num1<< " +-*/ "<< num2<< std::endl;
}
};
调用方式:
void testCanCallFunc() {
std::functiona = MyAdd;
std::functionb = MyMod;
std::functionc = MyDivide();
std::functiond = MyMul::mul;
MyClass myClass;
std::functione = std::bind(&MyClass::show, &myClass, std::placeholders::_1, 9527);
std::functionf = std::bind(&MyClass::show, &myClass, std::placeholders::_1, std::placeholders::_2);
std::cout<< a(111, 222)<< std::endl;
std::cout<< b(100, 200)<< std::endl;
std::cout<< c(200, 300)<< std::endl;
std::cout<< d(777, 888)<< std::endl;
e(1, 2);
f(4, 5);
auto fun1 = [] (int a1, int a2) {
std::cout<< a1<< " "<< a2<< std::endl;
};
auto myFun = [a, b, c, fun1](int a1, int a2){
std::cout<< a(a1, a2)<< std::endl;
std::cout<< b(a1, a2)<< std::endl;
std::cout<< c(a1, a2)<< std::endl;
fun1(a1, a2);
};
myFun(111, 333);
}
调用结果:
2. 成员函数指针当作形参调用成员函数如下定义两个类:
class TestClass1 {
public:
TestClass1() {}
~TestClass1() {}
void fun() { std::cout<< __FUNCTION__<< std::endl; }
void fun1() { std::cout<< __FUNCTION__<< std::endl; }
private:
};
class TestClass2 {
public:
TestClass2() {}
~TestClass2() {}
void fun() { std::cout<< __FUNCTION__<< std::endl; }
void fun1() { std::cout<< __FUNCTION__<< std::endl; }
void fun2(const int& num) { std::cout<< __FUNCTION__<< " "<< num<< std::endl; }
private:
};
调用其成员函数:
//成员函数指针形式参数,此处abxd和exf是形参数名字,可以随便起名字
void CallMemberFun(TestClass1& t1, void (TestClass1::*abxd)(),
TestClass2 t2, void (TestClass2::*exf)(),
void (TestClass2::*hello)(const int &a),
const int& num = 1234) {
(t1.*abxd)();
(t2.*exf)();
(t2.*hello)(num);
}
void testUseClassMemFunc() {
TestClass1 t1 = TestClass1();
CallMemberFun(t1, &TestClass1::fun1, TestClass2(),
&TestClass2::fun,
&TestClass2::fun2);
}
调用结果:
3. std::function作为形参调用成员函数//std::function充当形式参数,通过std::bind转换成员函数为std::function类型,来实现对成员函数的调用
void CallMemberFun(std::functionabxd,
std::functionexf,
std::functionhello,
const int& num = 1234) {
abxd();
exf();
hello(num);
}
void testUseClassMemUseFunciton() {
TestClass1 t1 = TestClass1();
auto aFun = std::bind(&TestClass1::fun1, &t1);
TestClass2 t2 = TestClass2();
auto aFun2 = std::bind(&TestClass2::fun2, &t2, std::placeholders::_1);
CallMemberFun(aFun, std::bind(&TestClass1::fun1, &t1), aFun2, 7788);
}
调用结果如下:
附录:
完整代码:
#include#include//普通函数
int MyAdd(int num1, int num2){ return num1+num2; }
//lambda表达式
auto MyMod = [](int num1, int num2){ return num1%num2; };
//函数对象类
struct MyDivide{
int operator()(int num1, int num2){
return num1/num2;
}
};
//类的静态成员函数
class MyMul {
public:
static int mul(int num1, int num2) {
return num1*num2;
}
};
//普通类的成员函数
class MyClass {
public:
void show(const int &num1 = 100, const int &num2 = 300) {
std::cout<< num1<< " +-*/ "<< num2<< std::endl;
}
};
class TestClass1 {
public:
TestClass1() {}
~TestClass1() {}
void fun() { std::cout<< __FUNCTION__<< std::endl; }
void fun1() { std::cout<< __FUNCTION__<< std::endl; }
private:
};
class TestClass2 {
public:
TestClass2() {}
~TestClass2() {}
void fun() { std::cout<< __FUNCTION__<< std::endl; }
void fun1() { std::cout<< __FUNCTION__<< std::endl; }
void fun2(const int& num) { std::cout<< __FUNCTION__<< " "<< num<< std::endl; }
private:
};
//成员函数指针形式参数,此处abxd和exf是形参数名字,可以随便起名字
void CallMemberFun(TestClass1& t1, void (TestClass1::*abxd)(),
TestClass2 t2, void (TestClass2::*exf)(),
void (TestClass2::*hello)(const int &a),
const int& num = 1234) {
(t1.*abxd)();
(t2.*exf)();
(t2.*hello)(num);
}
//std::function充当形式参数,通过std::bind转换成员函数为std::function类型,来实现对成员函数的调用
void CallMemberFun(std::functionabxd,
std::functionexf,
std::functionhello,
const int& num = 1234) {
abxd();
exf();
hello(num);
}
void testCanCallFunc() {
std::functiona = MyAdd;
std::functionb = MyMod;
std::functionc = MyDivide();
std::functiond = MyMul::mul;
MyClass myClass;
std::functione = std::bind(&MyClass::show, &myClass, std::placeholders::_1, 9527);
std::functionf = std::bind(&MyClass::show, &myClass, std::placeholders::_1, std::placeholders::_2);
std::cout<< a(111, 222)<< std::endl;
std::cout<< b(100, 200)<< std::endl;
std::cout<< c(200, 300)<< std::endl;
std::cout<< d(777, 888)<< std::endl;
e(1, 2);
f(4, 5);
auto fun1 = [] (int a1, int a2) {
std::cout<< a1<< " "<< a2<< std::endl;
};
auto myFun = [a, b, c, fun1](int a1, int a2){
std::cout<< a(a1, a2)<< std::endl;
std::cout<< b(a1, a2)<< std::endl;
std::cout<< c(a1, a2)<< std::endl;
fun1(a1, a2);
};
myFun(111, 333);
}
void testUseClassMemFunc() {
TestClass1 t1 = TestClass1();
CallMemberFun(t1, &TestClass1::fun1, TestClass2(),
&TestClass2::fun,
&TestClass2::fun2);
}
void testUseClassMemUseFunciton() {
TestClass1 t1 = TestClass1();
auto aFun = std::bind(&TestClass1::fun1, &t1);
TestClass2 t2 = TestClass2();
auto aFun2 = std::bind(&TestClass2::fun2, &t2, std::placeholders::_1);
CallMemberFun(aFun, std::bind(&TestClass1::fun1, &t1), aFun2, 7788);
}
int main(int argc, char *argv[]) {
testCanCallFunc();
std::cout<< "==================================="<< std::endl;
testUseClassMemFunc();
std::cout<< "==================================="<< std::endl;
testUseClassMemUseFunciton();
return 0;
}
运行结果如下:
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流