C++成员函数当作参数调用的两种方式-创新互联

平时编程时,多用来将数据进行传参,在考虑回调场景下我们会将函数单做参数传给被调用函数,让被调用函数在时机成熟时进行调用。在某些场景下,需要将类的成员函数当作参数进行回调,此时定义成员函数形参的方式通常有两种,以一种是成员函数指针类型,另外一种是使用std::function函数包装器。

目前成都创新互联公司已为千余家的企业提供了网站建设、域名、虚拟主机网站托管运营、企业网站设计、遂昌网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

目录

1. C++常见的可调用对象

(1) 普通函数

(2) lambda表达式

(3) 函数对象类

(4) 类的静态成员函数

(5) 类的普通成员函数

2. 成员函数指针当作形参调用成员函数

3. std::function作为形参调用成员函数


1. C++常见的可调用对象 (1) 普通函数
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元起,快前往官网查看详情吧


网站名称:C++成员函数当作参数调用的两种方式-创新互联
分享地址:http://csdahua.cn/article/cscoih.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流