переопределение или добавление функции-члена класса динамически / во время выполнения - PullRequest
3 голосов
/ 25 июля 2011

Эй, я пытаюсь создать очень простой графический интерфейс с использованием SFML, и я хочу иметь возможность присоединить функцию к моему классу Button в конструкторе, так что пользователь может определить, что происходит, когда кнопкапрессованная .

Я немного раньше работал с GLUT и заметил следующие отклонения:

glutReshapeFunc(Resize);
glutDisplayFunc(Draw);

которые, по-видимому, определяют , какую функцию следует вызывать при изменении размера или отображении окна,Я хочу что-то подобное для моей кнопки, чтобы при создании вы могли определить, какую функцию следует вызывать. Я хочу иметь возможность передавать имя функции точно так же, как и glut, без определения нового класса, который переопределяет виртуальную функцию.

  • Я также сомневаюсь, что возможно передать параметрыдля этих вызываемых функций, так как вы никогда не знаете, что или сколько их будет.Я прав?

Так или иначе ..... Как мне сделать это или что-то подобное ??Спасибо!

Ответы [ 3 ]

2 голосов
/ 25 июля 2011

Вы можете сохранить обратный вызов, используя, например, std::function (для C ++ 0x; boost::function также доступен и имеет аналогичный интерфейс).

#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
1 голос
/ 25 июля 2011

В C ++ лучше использовать virtual функциональный подход для решения подобных проблем.Это более удобно в долгосрочной перспективе.

Вы можете немного изменить дизайн своего кода, чтобы иметь общий дескриптор для различных подклассов.Теперь на основе выбранного подкласса вы можете вызывать определенную функцию.Например:

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

Теперь просто передайте дескриптор Shape* куда хотите и вызовите вышеупомянутые абстрактные методы;

void foo(Shape *p)
{
  p->Resize();
}
0 голосов
/ 25 июля 2011

(переписал все), я неправильно прочитал вопрос.

Похоже, вы хотите передать обычные указатели на функции другим функциям. Все, что вам нужно сделать, это просто передать имя нужной вам функции, но сделайте это внутри if (или что-то в этом роде), чтобы переданная функция была действительно той, что вы хотите:

if(i am feeling lucky today){
    glutDisplayFunc(DrawMyLuckyShape);
}else{
    glutDisplayFunc(DrawAFoo);
}

Плохая новость заключается в том, что, поскольку C - отвратительный язык, вы не можете настроить его для передачи дополнительных параметров вашим функциям (т. Е. Используйте замыкания). Следовательно, вам нужно полагаться на a) функции, которым передается некоторый вызываемый параметр quen, или b) функции, смотрящие на некоторое глобальное состояние.

...