Это правильный способ реализации пользовательских обработчиков событий? - PullRequest
1 голос
/ 12 августа 2011

Я искал способ добавления пользовательских обработчиков событий в качестве функции-члена класса c ++. Обнаружил, что этот код на самом деле работает. Мне нужно разделить библиотечный класс и пользовательский код, чтобы пользовательский код мог настраивать библиотечный класс. Вот концепция кода. Это правильно сделать? Безопасность нитей выходит за рамки моего вопроса. Компилятор gcc. Код пользователя очень и очень аккуратный. без наследования, виртуальные функции, используемые шаблоны

#include <stdio.h>

typedef void fn();

class aaa
{
  public:
  aaa() : customhandler(NULL) {}
  fn *customhandler;
};

// код пользователя start

void dostuff() {
  printf("doing stuff 1\n");
}
void dostuff2() {
  printf("doing stuff 2\n");
}
int main()
{
  aaa aaa1;
  aaa1.customhandler = &dostuff;
  aaa1.customhandler();
  aaa1.customhandler = &dostuff2;
  aaa1.customhandler();
}

Ответы [ 2 ]

2 голосов
/ 12 августа 2011

Ну, если бы у вас были библиотеки Boost или компилятор с поддержкой C ++ 0x, вы могли бы иметь такой код:

#include <cstdio>
#include <functional>

struct Foo
{
    std::function<void ()> handler;

    void invoke ()
    {
        if (handler)
        {
            handler ();
        }
        else
        {
            printf ("Oops, handler is not there!\n");
        }
    }
};

static void myHandler1 (int arg)
{
    printf ("Handler #1 (arg=%d)\n", arg);
}

static void myHandler2 ()
{
    printf ("Handler #2\n");
}

int main ()
{
    Foo f;

    f.invoke ();

    f.handler = std::bind (&myHandler1, 13);
    f.invoke ();

    f.handler = &myHandler2;
    f.invoke ();
}

Приятно то, что вы можете иметь функции илифункторы, связанные с обработчиком с необязательными дополнительными аргументами.

Ваш оригинальный код также будет работать, но что если я хочу вызвать метод класса, а не простую функцию?Что, если я хочу также передать какое-то состояние, к которому я могу получить доступ внутри обработчика, когда он вызывается?Это одна из многих причин, по которым std::function сделал это стандартом C ++.

1 голос
/ 12 августа 2011

Я попробовал ваш код, и он отлично работает.Просто для вашей информации, есть другой способ кодирования указателя вашей функции.В этом случае ваш код может быть немного упрощен.Здесь я использую немного другой синтаксис для typedef для указателя на функцию, который позволяет вам отбрасывать символы &.это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...