cpp中将类成员函数作为变量传递给函数

⌚Time: 2023-09-20 22:44:09

👨‍💻Author: Jack Ge

假设类ClassName有一个成员函数


void ClassName::funcname(int);

通过typedef定义一个类成员函数指针类型,参数和返回值类型都要与成员函数对应


typedef void (ClassName::*FuncPtr)(int); // 定义类成员函数指针

获取到的参数就是


FuncPtr pfunc;

在使用的地方如果是调用对象的成员函数可以是


(obj.*pfunc)(arg);


或者对指针形式的对象的成员函数调用


(obj->*pfunc)(arg);


传递参数的函数的参数形式




void use_func(ClassName *obj,&ClassName::pfunc,int arg){

    ...

    (obj->*pfunc)(arg);

}

向函数传递成员函数作为参数


ClassName obj;

int a = 3;

use_func(&obj,&ClassName::funcname,a);

演示

将B类里面say_hello作为参数,并且在其它类调用


#ifndef _B_H_

#define _B_H_

#include <iostream>

class B{

public:

    void say_hello(void){

        std::cout<<"B::hello\n";

    }

};

#endif

编辑一个类A


#ifndef _A_H_

#define _A_H_

class B;

//类成员函数指针类型

typedef void (B::*CALL_FUNC)(void);

class A{

public:

    //执行函数

    void run_func(B *arg0,CALL_FUNC arg1){

        if(arg0&&arg1){

            (arg0->*arg1)();

        }

    }

};

#endif

测试


#include "a.h"

#include "b.h"



int main(){

    B b;

    A a;

    a.run_func(&b,&B::say_hello);

    std::cin.get();

}

输出


B::hello

可以向run_func传递对象的指针,好处就是无需知道被调用成员函数的类B的定义,只需要对类B做一个前向声明就可以了。可以避免包含它的头文件,如果被对方类B头文件包含也不会发生头文件相互引用的情况。

也可以直接向run_func传递类对象,这种的情况就必须包含要调用的成员函数类B的头文件。修改后的代码




#ifndef _A_H_

#define _A_H_

#include "b.h"

//函数指针类型

typedef void (B::*CALL_FUNC)(void);

class A{

public:

    //执行函数

    void run_func(B arg0,CALL_FUNC arg1){

        if(arg1){

            (arg0.*arg1)();

        }

    }

};

#endif

使用


    B b;

    A a;

    a.run_func(b,&B::say_hello);

更多的,将类A修改


#ifndef _A_H_

#define _A_H_

class B;

//类成员函数指针类型

typedef void (B::*CALL_FUNC)(void);

class A{

public:

    void reg_func(B *arg0,CALL_FUNC arg1){

        parent = arg0;

        pFunc = arg1;

    }

    //执行函数

    void run_func(){

        if(parent&&pFunc){

            (parent->*pFunc)();

        }

    }

private:

    CALL_FUNC pFunc;

    B *parent;

};

#endif

类B就可以对A注册回调函数,发生某种情况时,A就可以调用B的方法进行处理


#ifndef _B_H_

#define _B_H_

#include "a.h"

#include <iostream>

class B{

public:

    B(){

        a.reg_func(this, &B::say_hello);

    }

    void say_hello(void){

        std::cout<<"B::hello\n";

    }

private:

    A a;

};

#endif