¿Cómo puedo pasar una función miembro a un puntero de función?

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 } }; 

¿Cómo puedo pasar una función de miembro a un puntero de función, y luego cómo llamaré a ese puntero de función?

No puedes. Pasa un puntero a un método estático o Parent debe aceptar también un puntero al objeto.

Es posible que desee consultar boost :: bind y boost :: function para eso:

 #include  #include  struct Y { void say(void) { std::cout << "hallo!";} boost::function getFunc() { return boost::bind(&Y::say, this); } }; struct X { //non-boost: void (Y::*func)(); Y* objectY; void callFunc() { (objectY->*func)(); } //boost version: boost::function f; }; X x; Y y; xf = boost::bind(&Y::say, boost::ref(y)); xf = y.getFunc(); xf(); x.func = &Y::say; x.objectY = &y; x.callFunc(); 

En respuesta a su última edición, para formar un puntero-a-miembro, debe usar & y classkey:: . No hay equivalente al nombre de la función para la conversión implícita de puntero a función para las funciones normales.

 // not valid: p.funcPointer3=TestFunc; // valid: p.funcPointer3 = &Child::TestFunc; 

Para acceder a un miembro a través de un puntero a miembro, debe usar el operador. .* O ->* .

P.ej

 (this->*p.funcPointer3)(); 

De hecho, podemos lograr los 3 de tus funcPointer* s en C ++ 11 con la llegada de las funciones de bind y Lambda . Hablemos de cada uno primero y hablemos de lo que están haciendo:

  1. funcPointer busca llamar a un método Child sin funcPointer un objeto Child , por lo que el objeto Child debería guardarse. El objeto hijo se podría guardar con un puntero: bind(&Child::TestFunc, this) O en C ++ 14 podría guardarse por valor: [arg = *this]() mutable { arg.TestFunc(); } [arg = *this]() mutable { arg.TestFunc(); }
  2. funcPointer2 busca llamar a un método Child con un Parent* . Podríamos hacer esto como: [](Parent* arg){ static_cast(arg)->TestFunc(); } [](Parent* arg){ static_cast(arg)->TestFunc(); } Por supuesto, esto no sería más legal que (new Parent)->TestFunc() por lo que estamos asumiendo que el Parent* es en realidad un Child* , si estaba dispuesto a hacer un tipo polimórfico Parent podría verificar antes de llamar a tu lambda:
 [](Parent* arg) { assert(dynamic_cast(arg) != nullptr); static_cast(arg)->TestFunc(); } 
  1. funcPointer3 busca almacenar un puntero a un método Child , y ya lo tienes funcionando. Solo necesita usar un objeto Child para llamarlo, por ejemplo: (this->*p.funcPointer3)() . Pero debe asignar funcPointer3 como este: funcPointer3 = &Child::TestFunc , porque si intenta hacer esto: funcPointer3 = &TestFunc obtendrá el error:

‘&’: operación ilegal en la expresión de la función miembro enlazado

A continuación, un puntero de función o un puntero de función miembro no se puede utilizar para hacer referencia a un Tipo de cierre , por lo que necesitaremos convertir los punteros de function objetos de function . ( funcPointer3 es solo un puntero de función miembro, por lo que no necesita convertirse, pero lo convertiré para demostrar que un objeto de function puede contener un puntero de función miembro y simplifica la llamada a: p.funcPointer(this) ) :

 class Parent { public: function funcPointer; function funcPointer2; function funcPointer3; }; 

Ahora que hemos adaptado Parent , podemos asignar fácilmente como se demostró en 1 , 2 y 3 :

 void Child::Do() { Parent p; p.funcPointer = bind(&Child::TestFunc, this); p.funcPointer2 = [](Parent* arg) { static_cast(arg)->TestFunc(); }; p.funcPointer3 = &Child::TestFunc; p.funcPointer(); p.funcPointer2(this); p.funcPointer3(this); } 

Probablemente lo sepas y solo estabas probando, pero podríamos haber usado fácilmente los miembros de Parent Child heredados, ya que podríamos crear un nuevo objeto Parent en Child::Do Voy a cambiar eso y arrojar el código en un ejemplo: http://ideone.com/yD7Rom