Программирование на языке C ++ реализует функцию обратного вызова функции класса - PullRequest
0 голосов
/ 08 апреля 2020

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

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

Я не знаю, как написать callback callback в Manager::send?

Это мой полуфабрикат код:

enum EventType
{
    Test1,
    Test2,
    Test3,
};

class CallbackInterface
{

};

template <typename Return, typename ...T>
class BaseCallback : public CallbackInterface
{
public:
    virtual ~BaseCallback() {}
    virtual Return operator() (T... args) = 0;
};

template <typename Object, typename Return, typename ...T>
class MemberFunctionCallback : public BaseCallback<Return, T...>
{
public:
    MemberFunctionCallback(Object* object, Return(Object::* function)(T...))
    {
        this->object = object;
        this->function = function;
    }

    virtual Return operator() (T... args)
    {
        return ((this->object)->*(this->function))(args...);
    }

private:
    Object* object;
    Return(Object::* function)(T...);
};

class Test {
public:
    void function(int i) {
        // Do something...
    }
};

class Manager {
public:
    void bind(EventType eventType, CallbackInterface* callbackInterface)
    {
        if (this->callbackMap.find(eventType) == this->callbackMap.end())
        {
            this->callbackMap[eventType] = new std::vector<CallbackInterface*>();
        }

        this->callbackMap[eventType]->push_back(callbackInterface);
    }

    template<typename ...T>
    void send(EventType eventType, T... args)
    {
        std::vector<CallbackInterface*>* list = this->callbackMap[eventType];

        for (CallbackInterface* item : list)
        {
            // Invoke callback
            // How to write here? I am not very familiar with template programming.
        }
    }

private:
    std::map<EventType, std::vector<CallbackInterface*>*> callbackMap;

};

int main() {
    Manager manager;
    Test test;

    manager.bind(EventType::Test1, new MemberFunctionCallback<Test, void, int>(&test, &Test::function));

    manager.send(EventType::Test1, 12); // Call the registered callback

    system("pause");
    return 0;
}
...