none
请问大佬们,如何写一个 接收类成员函数指针类型 的函数?? RRS feed

  • 问题

  • 假设有一个类,

    class MyClass {
    public:
    	void memberFunc(int n) {
    		cout << "调用非静态成员函数" << endl;
    	}
    };

    那么指向MyClass类void memberFunc(int)的函数指针类型应该是:

    void (MyClass::*) (int);

    参考微软的文档https://docs.microsoft.com/zh-cn/cpp/error-messages/compiler-errors-1/compiler-error-c2064?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DZH-CN%26k%3Dk(C2064)%26rd%3Dtrue%26f%3D255%26MSPPError%3D-2147217396&view=vs-2019,我这样写的:

    class MyClass {
    public:
    	void memberFunc(int n) {
    		cout << n << endl;
    	}
    };
    
    typedef void (MyClass::*MemberFuncPointerType) (int);
    
    template <typename T>
    void recevieMemberFunc(T myClass, MemberFuncPointerType memFunc) {
    	(myClass.*memFunc)(100);
    }
    
    int main()
    {
    	MyClass myClass;
    	recevieMemberFunc<MyClass>(myClass, &MyClass::memberFunc);
    }

    但是我将 recevieMemberFunc函数 修改为如下形式,为什么就不行了。

    template <typename T>void recevieMemberFunc( void ( T::*)(int) memFunc ) {}

    或者这样定义,也报错。

    template <typename T>
    void recevieMemberFunc(T myClass,void (T::)(int)& memFunc) {}





    2019年10月13日 14:45

答案

  • 你好,

    感谢你在MSDN论坛发帖。

    可以参考一下底下两个demo。第一个demo针对你想要一个类成员函数的指针的情况。

    #include <iostream>
    using namespace std;
    class MyClass 
    {
    public:
    	void memberFunc(int n)
    	{
    		cout << "MyClass::memberFunc()" << endl;
    	}
    };
    
    typedef void(MyClass::*fc)(int);//定义一个指针,这个指针要与目标函数同类,同返回值类型,同参数类型
    
    int main()
    {
    	MyClass a;
    	fc fc1 = &MyClass::memberFunc; //指针赋值,利用&取函数地址 
        (a.*fc1)(1);//fc1就是MyClass::memberFunc()函数的指针
    }

    第二个demo虽然我做出了你所需要的效果,但这么做的意义并没有,这个模板类只适用于MyClass类,这样他作为一个模板类存在有什么必要性。另外这样做也非常复杂,既然把类对象作为参数传进函数,那这样已经可以调用类对象的方法来做了,又何必要传类成员函数指针呢。类成员函数指针还是需要依托于类对象才能调用,类成员函数指针始终是指针,没有实例化的对象,它也就没什么意义。

    #include <iostream>
    using namespace std;
    class MyClass 
    {
    public:
    	int FunA(int a, int b) 
    	{
    		cout << "call FunA" << endl;
    		cout << a+b << endl;
    		return a + b;
    	}
    };
    
    typedef int (MyClass::*fc)(int,int);//定义一个指针,这个指针要与目标函数同类,同返回值类型,同参数类型
    
    template <typename T>
    void recevieMemberFunc(T a, fc fc1)
    {
    	(a.*fc1)(1, 2);//通过类成员函数指针调用函数
    	a.FunA(1, 2);//通过类对象直接调用成员函数
    }
    
    int main()
    {
    	MyClass a;
    	fc fc1 = &MyClass::FunA;
    	recevieMemberFunc<MyClass>(a,fc1);
    }

    Best Regards,

    Suarez Zhou




    2019年10月14日 2:52
  • “template <typename T>void recevieMemberFunc( void ( T::*)(int) memFunc ) {}”,c++里面没有这种写法。应该是:

    template <typename T>void recevieMemberFunc(void (T::*memFunc)(int)) {}

    2019年10月14日 4:02

全部回复

  • 你好,

    感谢你在MSDN论坛发帖。

    可以参考一下底下两个demo。第一个demo针对你想要一个类成员函数的指针的情况。

    #include <iostream>
    using namespace std;
    class MyClass 
    {
    public:
    	void memberFunc(int n)
    	{
    		cout << "MyClass::memberFunc()" << endl;
    	}
    };
    
    typedef void(MyClass::*fc)(int);//定义一个指针,这个指针要与目标函数同类,同返回值类型,同参数类型
    
    int main()
    {
    	MyClass a;
    	fc fc1 = &MyClass::memberFunc; //指针赋值,利用&取函数地址 
        (a.*fc1)(1);//fc1就是MyClass::memberFunc()函数的指针
    }

    第二个demo虽然我做出了你所需要的效果,但这么做的意义并没有,这个模板类只适用于MyClass类,这样他作为一个模板类存在有什么必要性。另外这样做也非常复杂,既然把类对象作为参数传进函数,那这样已经可以调用类对象的方法来做了,又何必要传类成员函数指针呢。类成员函数指针还是需要依托于类对象才能调用,类成员函数指针始终是指针,没有实例化的对象,它也就没什么意义。

    #include <iostream>
    using namespace std;
    class MyClass 
    {
    public:
    	int FunA(int a, int b) 
    	{
    		cout << "call FunA" << endl;
    		cout << a+b << endl;
    		return a + b;
    	}
    };
    
    typedef int (MyClass::*fc)(int,int);//定义一个指针,这个指针要与目标函数同类,同返回值类型,同参数类型
    
    template <typename T>
    void recevieMemberFunc(T a, fc fc1)
    {
    	(a.*fc1)(1, 2);//通过类成员函数指针调用函数
    	a.FunA(1, 2);//通过类对象直接调用成员函数
    }
    
    int main()
    {
    	MyClass a;
    	fc fc1 = &MyClass::FunA;
    	recevieMemberFunc<MyClass>(a,fc1);
    }

    Best Regards,

    Suarez Zhou




    2019年10月14日 2:52
  • “template <typename T>void recevieMemberFunc( void ( T::*)(int) memFunc ) {}”,c++里面没有这种写法。应该是:

    template <typename T>void recevieMemberFunc(void (T::*memFunc)(int)) {}

    2019年10月14日 4:02
  • 明白了,函数指针和一般的变量定义不太一样吧,平常都是: 类型名 变量, 但函数指针不是。

    所以,得像定义函数指针变量那样, 用同样的方式在函数接口处声明那样的函数形参。


    class MyClass
    {
    public:
    	void memberFunc() {
    		std::cout << "调用成员函数" << std::endl;
    	}
    	static void staticMemberFunc() {
    		std::cout << "调用静态成员函数" << std::endl;
    	}
    private:
    
    };
    
    template <typename T>
    void receiveMemberFunc(T myclass, void (T::*memberFunc)()  ) {
    	(myclass.*memberFunc)();
    }
    
    int main()
    {
    	
    	MyClass test;
    	receiveMemberFunc<MyClass>(test, &MyClass::memberFunc);
    }

    2019年10月14日 8:03