Универсальный диспетчер для нескольких классов

#c

#c

Вопрос:

Я пытаюсь добиться того же эффекта в C . В Python так просто просто передать указатель на метод класса диспетчеру и выполнить обратный вызов функции при возникновении определенного события. Эффект, который я ищу, — это настоящий универсальный метод класса диспетчеризации. Кроме того, классы не должны быть каким-либо образом связаны (как в примере ниже).

 class Dispatcher:
    def __init__(self):
        self.map = {}

    def register(self, func, event):
        try:
            self.map[event].append(func)
        except KeyError:
            self.map[event] = [func]

    def dispatch(self, event):
        for func in self.map[event]:
            func(event)

class A:
    def __init__(self):
        pass

    def foo(self, event):
        print("A", event)

class B:
    def __init__(self):
        pass

    def bar(self, event):
        print("B", event)

if __name__ == '__main__':
    d = Dispatcher()
    a = A()
    b = B()
    d.register(a.foo, 6)
    d.register(b.bar, 6)
    d.register(a.foo, 7)

    d.dispatch(6)
 

Ожидаемый результат:

 A 6
B 6
 

Комментарии:

1. Посмотрите, работает ли для вас какой-либо из этих вариантов: embeddedartistry.com/blog/2017/02/01 /…

2. И это так же просто в C с std::bind и std::function ….

3. Вам даже не нужно использовать std::bind , просто лямбда, который захватывает this . Миссия выполнена.

4. std::map<int, std::function<void(int)>> ?

Ответ №1:

 #include <map>
#include <vector>
#include <functional>

using namespace std;

class dispatcher
{
public:
    using event_t = int;
    using callback_t = function<void(event_t)>;
    void register(callback_t c, event_t e)
    {
        m[e].emplace_back(move(c));
    }
    void dispatch(event_t e)
    {
        for(autoamp;amp;c: m[e])
            c(e);
    }
private:
    map<event_t, vector<callback_t>> m;
};
 

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

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

 A a;
d.register([amp;](int i){a.foo(i);}, 6);