Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redefining or adding a classes member function dynamically/ during execution

Hey i'm trying to make a very simple GUI using SFML, and i want to be able to attach a function to my Button class in the constructor, as so the user can define what happens when the button is pressed.

I've worked a little before with GLUT and noticed these declerations:

glutReshapeFunc(Resize);
glutDisplayFunc(Draw);

Which apparently define what function should be called when the window is resized or displayed. I want something exactly like this for my button so upon construction you can define what function should be called. I want to be able to pass a function name just like glut, not having define a new class wich overides a virtual functin.

  • I also doubt it's possible however to pass parameters for these called functions, as you never know what or how many there would be. Am i right?

So anyway..... How do i accomplish this or something like it?? Thanks!

like image 957
Griffin Avatar asked May 24 '26 02:05

Griffin


2 Answers

You can store a callback using e.g. std::function (for C++0x; boost::function is also available and has a similar interface).

#include <functional>

class Button {
public:
    template<typename T>
    explicit
    Button(T const& t): callback(t) {}

    void
    press()
    {
        callback();
    }

private:
    std::function<void()> callback;
};

// example use with a lambda
Button b([] { do_stuff(); });
b.press(); // will call do_stuff
like image 200
Luc Danton Avatar answered May 26 '26 20:05

Luc Danton


In C++ it's better to use virtual function approach to address such kind of problems. That's more maintainable at long run.

You can choose to redesign a little bit to your code, where you can have a common handle to various subclasses. Now based on subclass chosen you can call a particular function. For example:

class Shape
{
public:
  virtual void Resize () = 0;
  virtual void Draw () = 0;
};

class Triangle : public Shape
{
public:
//  implement above to functions
};

class Square : public Shape
{
public:
//  implement above to functions
};

Now, just pass the handle of Shape* wherever you want and call the above abstract methods;

void foo(Shape *p)
{
  p->Resize();
}
like image 38
iammilind Avatar answered May 26 '26 19:05

iammilind