Funktion als Parameter übergeben?



  • Hi, kurze frage, wie kann ich eine funktion an meine methode als parameter übergeben, in ner klassenvariable speichern und dann später ausführen? übergeb ich nen pointer auf die funktion? wie kann ich sie dann aufrufen? thx



  • Genau, ein Zeiger auf die Funktion übergeben:

    #include <iostream>
    
    int add( int a, int b )
    {
    	return a+b;
    }
    
    void foo( int a, int b, int ( *funptr )( int, int ) )
    {
    	std::cout << funptr( a, b );
    }
    
    int main()
    {
    	foo( 10, 20, add );
    	std::cin.get();
    }
    


  • vielen Dank!



  • hmm funktionier irgendwie nicht:

    void pressTest()
    {
    	quit = true;
    	MessageBox(0,"","",0);
    }
    void initButtons()
    {
    	/*for (list<SDL_Button*>::iterator i = buttonList.begin(); i != buttonList.end(); ++i) { 
    	//
    	}*/
    
    	SDL_Button test(loadBmp("testbutton.bmp"), loadBmp("testbutton.bmp"), loadBmp("testbutton.bmp"), "test", /* HIER wird die funktion übergeben*/pressTest, Vektor(10,10));
    	test.paint(screen);
    	buttonList.push_back(test);
    }
    

    hier ist der button cton:

    SDL_Button::SDL_Button(SDL_SurfaceWrapper sNormal, SDL_SurfaceWrapper sHover, SDL_SurfaceWrapper sPressed, std::string label, void ( * onPress ), Vektor pos)
    {
    	this->sNormal = sNormal;
    	this->sHover = sHover;
    	this->sPressed = sPressed;
    	this->label = label;
    	this->onPress = onPress;
    	this->pos = pos;
    	this->state = 0;
    }
    

    und hier soll die funktion aufgerufen werden:

    void SDL_Button::setPressedState(Vektor mousePos)
    {
    	SDL_Surface *cSurf;
    	switch(state)
    	{
    	case 0:
    		cSurf = sNormal.surface;
    	case 1:
    		cSurf = sHover.surface;
    	case 2:
    		cSurf = sPressed.surface;
    	default:
    		cSurf = sNormal.surface;
    	};
    	if(mousePos.x >= pos.x && mousePos.x <= pos.x+cSurf->w)
    	{
    		if(mousePos.y >= pos.y && mousePos.y <= pos.y+cSurf->h)
    		{
    			onPress(); // <------------------------------------
    			state = 1;
    		}
    		else
    			state = 0;
    	}
    	else
    	{
    		state = 0;
    	}
    }
    

    SDL_Button.cpp
    E:\Uni\code\PixGraph\SDL_Button.cpp(66) : error C2084: Funktion 'void __thiscall SDL_Button::setPressedState(class Vektor)' hat bereits einen Funktionsrumpf
    E:\Uni\code\PixGraph\SDL_Button.cpp(83) : error C2064: Ausdruck ergibt keine Funktion



  • Klammern vergessen?

    void ( * onPress )(), Vektor pos)
    


  • David_pb schrieb:

    Klammern vergessen?

    void ( * onPress )(), Vektor pos)
    

    stimmt, bekomme aber auch mit klammern de gleichen fehler 😞



  • Mich würd mal die Klassendefiniton interessieren.



  • David_pb schrieb:

    Mich würd mal die Klassendefiniton interessieren.

    #ifndef SDL_Button_h
    #define SDL_Button_h 1
    #include "SDL/SDL.h"
    #include "SDL/SDL_ttf.h"
    #include <string>
    #include "Vektor.h"
    #include "SDL_SurfaceWrapper.h"
    
    class SDL_Button
    {
    public:
    	//cton
    	SDL_Button(SDL_SurfaceWrapper sNormal, SDL_SurfaceWrapper sHover, SDL_SurfaceWrapper sPressed, std::string label, void (*onPress)(), Vektor pos);
    
    	void setHoverState(Vektor mousePos);
    	void setPressedState(Vektor mousePos);
    	void setClickedState(Vektor mousePos);
    	Vektor getPos();
    
    	void setPos(Vektor v);
    	void setPos(int x, int y);
    	std::string getLabel();
    	void setLabel(std::string nLabel);
    	void paint(SDL_Surface *to);
    	virtual ~SDL_Button();
    
    private:
    	SDL_SurfaceWrapper sNormal;
    	SDL_SurfaceWrapper sHover;
    	SDL_SurfaceWrapper sPressed;
    	std::string label;
    	void *onPress;
    	Vektor pos;
    	int state; //0-> normal, 1-> hover, 2-> pressed
    };
    #endif
    
    #include "SDL_Button.h"
    
    SDL_Button::SDL_Button(SDL_SurfaceWrapper sNormal, SDL_SurfaceWrapper sHover, SDL_SurfaceWrapper sPressed, std::string label, void ( * onPress )(), Vektor pos)
    {
    	this->sNormal = sNormal;
    	this->sHover = sHover;
    	this->sPressed = sPressed;
    	this->label = label;
    	this->onPress = onPress;
    	this->pos = pos;
    	this->state = 0;
    }
    void SDL_Button::setHoverState(Vektor mousePos)
    {
    	SDL_Surface *cSurf;
    	switch(state)
    	{
    	case 0:
    		cSurf = sNormal.surface;
    		break;
    	case 1:
    		cSurf = sHover.surface;
    		break;
    	case 2:
    		cSurf = sPressed.surface;
    		break;
    	default:
    		cSurf = sNormal.surface;
    		break;
    	};
    	if(mousePos.x >= pos.x && mousePos.x <= pos.x+cSurf->w)
    	{
    		if(mousePos.y >= pos.y && mousePos.y <= pos.y+cSurf->h)
    			state = 1;
    		else
    			state = 0;
    	}
    	else
    	{
    		state = 0;
    	}
    }
    void SDL_Button::setPressedState(Vektor mousePos)
    {
    	SDL_Surface *cSurf;
    	switch(state)
    	{
    	case 0:
    		cSurf = sNormal.surface;
    		break;
    	case 1:
    		cSurf = sHover.surface;
    		break;
    	case 2:
    		cSurf = sPressed.surface;
    		break;
    	default:
    		cSurf = sNormal.surface;
    		break;
    	};
    	if(mousePos.x >= pos.x && mousePos.x <= pos.x+cSurf->w)
    	{
    		if(mousePos.y >= pos.y && mousePos.y <= pos.y+cSurf->h)
    			state = 2;
    		else
    			state = 0;
    	}
    	else
    	{
    		state = 0;
    	}
    }
    void SDL_Button::setPressedState(Vektor mousePos)
    {
    	SDL_Surface *cSurf;
    	switch(state)
    	{
    	case 0:
    		cSurf = sNormal.surface;
    		break;
    	case 1:
    		cSurf = sHover.surface;
    		break;
    	case 2:
    		cSurf = sPressed.surface;
    		break;
    	default:
    		cSurf = sNormal.surface;
    		break;
    	};
    	if(mousePos.x >= pos.x && mousePos.x <= pos.x+cSurf->w)
    	{
    		if(mousePos.y >= pos.y && mousePos.y <= pos.y+cSurf->h)
    		{
    			onPress();
    			state = 1;
    		}
    		else
    			state = 0;
    	}
    	else
    	{
    		state = 0;
    	}
    }
    
    Vektor SDL_Button::getPos()
    {
    	return pos;
    }
    void SDL_Button::setPos(Vektor v)
    {
    	pos = v;
    }
    void SDL_Button::setPos(int x, int y)
    {
    	pos.x = x;
    	pos.y = y;
    }
    std::string SDL_Button::getLabel()
    {
    	return label;
    }
    void SDL_Button::setLabel(std::string nLabel)
    {
    	label = nLabel;
    }
    void SDL_Button::paint(SDL_Surface *to)
    {
    	switch(state)
    	{
    	case 0:
    		sNormal.blitTo(to, pos.x, pos.y);
    		break;
    	case 1:
    		sHover.blitTo(to, pos.x, pos.y);
    		break;
    	case 2:
    		sPressed.blitTo(to, pos.x, pos.y);
    		break;
    	default:
    		sNormal.blitTo(to, pos.x, pos.y);
    		break;
    	};
    }
    SDL_Button::~SDL_Button()
    {
    
    }
    


  • Hi!

    Du hast die Methode SetPressedState zweimal definiert. Außerdem:

    class SDL_Button
    {
     // ...
      typedef void ( *funptr_type )();
    
      SDL_Button( ......, funptr_type onpress_ );
    
    private:
      funptr_type onpress;
    };
    


  • ups, copy & paste ftw...sollte eigentlich anders heißen.. aber thx jetzt gehts



  • Ein typedef mach sowas leichter lesbar:

    void foo(int bar);
    typedef void (*myFunc) (int);
    
    void bar(myFunc huhu, int param_to_func)
    {
        huhu(param_to_func);
    }
    

    Oder alternativ auch einen Funktor.

    MfG Kimmi


Anmelden zum Antworten