C++ 如何将成员函数传递给函数指针?

C++ 如何将成员函数传递给函数指针?,c++,methods,function-pointers,member-function-pointers,delayed-execution,C++,Methods,Function Pointers,Member Function Pointers,Delayed Execution,如何将成员函数传递给函数指针,然后如何调用该函数指针?您不能。您可以传递指向静态方法的指针,或者父对象也必须接受指向该对象的指针 您可能需要查看并了解以下信息: class Child; class Parent { public: void (*funcPointer)(); void (*funcPointer2)(Parent* _this); void (Child::*funcPointer3)(); }; class Child: public Parent { pub

如何将成员函数传递给函数指针,然后如何调用该函数指针?

您不能。您可以传递指向静态方法的指针,或者父对象也必须接受指向该对象的指针

您可能需要查看并了解以下信息:

class Child;
class Parent
{
public:
  void (*funcPointer)();
  void (*funcPointer2)(Parent* _this);
  void (Child::*funcPointer3)();
};

class Child: public Parent
{
public:
  void TestFunc(){

  }
  void Do(){
    Parent p;
    p.funcPointer=TestFunc; // error, '=': cannot convert from 'void (__thiscall Child::* )(void)' to 'void (__cdecl *)(void)'
    p.funcPointer2=TestFunc; // error too, '=': cannot convert from 'void (__thiscall Child::* )(void)' to 'void (__cdecl *)(Parent *)'
    p.funcPointer3=TestFunc; //this works
    p.funcPointer3=&Child::TestFunc; // this works too.
    p.funcPointer3();    // error, term does not evaluate to a function taking 0 arguments
  }
};
#包括
#包括
结构
{
void say(void){std::cout*func();}
//增强版:
boost::函数f;
};
X;
Y;
x、 f=boost::bind(&Y::比方说,boost::ref(Y));
x、 f=y.getFunc();
x、 f();
x、 func=&Y::say;
x、 objectY=&y;
x、 callFunc();

为了响应上一次编辑,要形成指向成员的指针,必须使用
&
classkey::
。对于普通函数,函数名到指针到函数的隐式转换是不等价的

#include <boost/bind.hpp>
#include <boost/function.hpp>
struct Y
{
    void say(void) { std::cout << "hallo!";}

    boost::function<void()> getFunc() { return boost::bind(&Y::say, this); }
};

struct X
{
    //non-boost:
    void (Y::*func)();
    Y* objectY;
    void callFunc() { (objectY->*func)(); }

    //boost version:
    boost::function<void()> f;

};


X x;
Y y;
x.f = boost::bind(&Y::say, boost::ref(y));
x.f = y.getFunc();
x.f();
x.func = &Y::say;
x.objectY = &y; 
x.callFunc();
要通过指向成员的指针访问成员,必须使用
*
->*
运算符

例如


随着和的出现,我们实际上可以在C++11中完成所有3个
funcPointer*
s。让我们先讨论每一个,然后讨论他们正在做什么:

  • funcPointer
    试图调用
    Child
    方法而不接收
    Child
    对象,因此必须保存
    Child
    对象。子对象可以通过指针保存:
    bind(&child::TestFunc,this)
    或者在C++14中,它可以通过值保存:
    [arg=*this]()可变的{arg.TestFunc();}
  • funcPointer2
    试图使用
    Parent*
    调用
    子方法。我们可以这样做:
    [](Parent*arg){static_cast(arg)->TestFunc();}
    当然,这不会比
    (new Parent)->TestFunc()
    更合法,所以我们假设
    父*
    实际上是一个
    子*
    ,如果您愿意在调用lambda之前进行
    Parent
    a验证:
  • 现在我们已经调整了
    Parent
    ,我们可以很容易地分配,如123中所示:

    class Parent {
    public:
        function<void()> funcPointer;
        function<void(Parent*)> funcPointer2;
        function<void(Child*)> funcPointer3;
    };
    
    void子项::Do(){
    亲本p;
    p、 funcPointer=bind(&Child::TestFunc,this);
    p、 funcPointer2=[](父*arg){static_cast(arg)->TestFunc();};
    p、 funcPointer3=&Child::TestFunc;
    p、 funcPointer();
    p、 funcPointer2(本);
    p、 funcPointer3(本);
    }
    

    您可能知道这一点,并且只是在测试,但是我们可以轻松地使用继承自
    父对象的成员,就像我们可以在
    子对象::Do
    中创建新的
    父对象一样。我将切换这个选项,并在一个示例中抛出代码:

    还添加了一个非boost版本。这正是我想要的!我现在在VisualStudioC++ 6中编码,我不确定它支持Booo::你知道吗?我添加了必需的include,所以你只需要获得boost并尝试一下。但是它看起来不支持VS6.0,但这并不意味着绑定和函数不能在那里工作。我可以补充一点,MSVS2010或GCC4.4+添加了对C++0X中的
    std::function
    std::bind
    的支持,这是一种未来的标准方式来做这类事情。好的一点。但是这个特性在MSVC6中肯定永远不可用:-)这确实有效,我必须告诉编译器成员函数指针要使用哪个对象。谢谢大家!@在C++ 11之前,这是最好的答案,不需要用Boo..t.J.CuuldRunter来扩展你的可执行文件。你可以在这里找到修正的C++ FAQ链接:但是我再次相信它是无关的,因为它警告成员函数指针的传递,而不是成员函数指针的使用。
    (this->*p.funcPointer3)();
    
    [](Parent* arg) {
        assert(dynamic_cast<Child*>(arg) != nullptr);
    
        static_cast<Child*>(arg)->TestFunc();
    }
    
    class Parent {
    public:
        function<void()> funcPointer;
        function<void(Parent*)> funcPointer2;
        function<void(Child*)> funcPointer3;
    };
    
    void Child::Do() {
        Parent p;
    
        p.funcPointer = bind(&Child::TestFunc, this);
        p.funcPointer2 = [](Parent* arg) { static_cast<Child*>(arg)->TestFunc(); };
        p.funcPointer3 = &Child::TestFunc;
        p.funcPointer();
        p.funcPointer2(this);
        p.funcPointer3(this);
    }