sirven que punteros puntero parametros para los funciones con como cadenas arreglos aritmetica c++ class function pointers member

c++ - que - punteros y arreglos en c



¿Cómo se pasa un puntero de función miembro? (6)

¿No estaría mejor servido para usar OO estándar? Defina un contrato (clase virtual) e impleméntelo en su propia clase, luego simplemente pase una referencia a su propia clase y deje que el receptor llame a la función de contrato.

Usando su ejemplo (he cambiado el nombre del método ''test2'' a ''buttonAction''):

class ButtonContract { public: virtual void buttonAction(); } class testMenu : public MenuScreen, public virtual ButtonContract { public: bool draw; MenuButton<testMenu> x; testMenu():MenuScreen("testMenu") { x.SetButton(100,100,TEXT("buttonNormal.png"), TEXT("buttonHover.png"), TEXT("buttonPressed.png"), 100, 40, &this); draw = false; } //Implementation of the ButtonContract method! void buttonAction() { draw = true; } };

En el método del receptor, almacena la referencia a un ButtonContract, luego, cuando desea realizar la acción del botón simplemente llame al método ''buttonAction'' de ese objeto ButtonContract almacenado.

Estoy intentando pasar una función de miembro dentro de una clase a una función que toma un puntero de clase de función miembro. El problema que estoy teniendo es que no estoy seguro de cómo hacer esto correctamente dentro de la clase con este puntero. ¿Alguien tiene sugerencias?

Aquí hay una copia de la clase que está pasando la función miembro:

class testMenu : public MenuScreen{ public: bool draw; MenuButton<testMenu> x; testMenu():MenuScreen("testMenu"){ x.SetButton(100,100,TEXT("buttonNormal.png"),TEXT("buttonHover.png"),TEXT("buttonPressed.png"),100,40,&this->test2); draw = false; } void test2(){ draw = true; } };

La función x.SetButton (...) está contenida en otra clase, donde "objeto" es una plantilla.

void SetButton(int xPos, int yPos, LPCWSTR normalFilePath, LPCWSTR hoverFilePath, LPCWSTR pressedFilePath, int Width, int Height, void (object::*ButtonFunc)()) { BUTTON::SetButton(xPos, yPos, normalFilePath, hoverFilePath, pressedFilePath, Width, Height); this->ButtonFunc = &ButtonFunc; }

Si alguien tiene algún consejo sobre cómo puedo enviar correctamente esta función para que pueda usarla más tarde.


En el raro caso de que desarrolle con Borland C ++ Builder y no le moleste escribir código específico para ese entorno de desarrollo (es decir, código que no funcionará con otros compiladores de C ++), puede usar la palabra clave __closure . Encontré un pequeño artículo sobre cierres de C ++ Builder . Están destinados principalmente para su uso con Borland VCL.


Otros te han dicho cómo hacerlo correctamente. Pero me sorprende que nadie te haya dicho que este código es realmente peligroso:

this->ButtonFunc = &ButtonFunc;

Como ButtonFunc es un parámetro, saldrá del alcance cuando la función regrese. Usted está tomando su dirección. Obtendrá un valor de tipo void (object::**ButtonFunc)() ( puntero a un puntero a una función miembro ) y asígnelo a este-> ButtonFunc. En el momento en que intentes usar esto-> ButtonFunc intentarás acceder al almacenamiento del parámetro local (que ahora ya no existe), y tu programa probablemente se bloquee.

Estoy de acuerdo con la solución de Commodore. Pero debes cambiar su línea a

((ButtonObj)->*(ButtonFunc))();

ya que ButtonObj es un puntero al objeto.


Para llamar a una función miembro mediante un puntero, necesita dos cosas: un puntero al objeto y un puntero a la función. Necesita ambos en MenuButton::SetButton()

template <class object> void MenuButton::SetButton(int xPos, int yPos, LPCWSTR normalFilePath, LPCWSTR hoverFilePath, LPCWSTR pressedFilePath, int Width, int Height, object *ButtonObj, void (object::*ButtonFunc)()) { BUTTON::SetButton(xPos, yPos, normalFilePath, hoverFilePath, pressedFilePath, Width, Height); this->ButtonObj = ButtonObj; this->ButtonFunc = ButtonFunc; }

Luego puede invocar la función usando ambos punteros:

((ButtonObj)->*(ButtonFunc))();

No olvide pasar el puntero a su objeto a MenuButton::SetButton() :

testMenu::testMenu() :MenuScreen("testMenu") { x.SetButton(100,100,TEXT("buttonNormal.png"), TEXT("buttonHover.png"), TEXT("buttonPressed.png"), 100, 40, this, test2); draw = false; }



Sé que este es un tema bastante antiguo. Pero hay una forma elegante de manejar esto con c ++ 11

#include <functional>

declara tu puntero de función como este

typedef std::function<int(int,int) > Max;

declara tu la función de pasar esta cosa a

void SetHandler(Max Handler);

supongamos que le pasas una función normal, puedes usarla como siempre

SetHandler(&some function);

supongamos que tiene una función miembro

class test{ public: int GetMax(int a, int b); ... }

en tu código puedes pasarlo usando std::placeholders como este

test t; Max Handler = std::bind(&test::GetMax,&t,std::placeholders::_1,std::placeholders::_2); some object.SetHandler(Handler);