Определение методов вне области видимости класса с помощью указателей на функции - PullRequest
0 голосов
/ 23 октября 2018

Предисловие

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

Теоретически это звучит замечательно, но на самом деле я не уверен, возможно ли реализовать подобные вещи в C ++.Вот пример того, как я представляю, как выглядит код.


Схема

#include <iostream>

enum Color{ red, green, blue };

class Event {
public:
    // Would be called within the context of a loop.
    // Each time we go through the loop, we would have different input.
    void listen(const Color& color) {
        // If the callable is defined, then call it.
        if(callable) callable(color);
    }

    // We would pass in function to be called within listen()
    void defineAction(void(*function)(const Color &color)) {
        callable = function;
    }
private:
    void (*callable)(const Color& color) = nullptr;
};

class Greeter: public Event {
    void greet() { std::cout << "Hello" << std::endl; }
};

int main(int argc, char** argv) {
    Greeter greeter;

    // This doesn't work for two reasons. We cannot define a function here,
    // and scoping rules wont allow for an implicit this->greet().
    // Ideally, I would like to do this inline with a lambda
    /*void greetIfRed(const Color& color) {
        if(color == red)
            // call greet().
    }
    greeter.defineAction(&greetIfRed);
    */
}

Расширение этой идеи

По сути, класс Event будет получать что-то, что будет меняться каждый раз, когда мы проходим цикл обработки событий.Я выбрал цвет для этого примера, но это могут быть координаты мыши, целое число или что-то еще.Этот тип должен быть строго определен заранее.

В моем проекте я не хочу, чтобы это имело значение, какие классы мы имеем в цикле событий.У нас может быть приветствующий, игрок или что-то, что просто прощается.Я представляю, что цикл обработки событий будет выглядеть примерно так.(psuedocode)

while(event) {
    greeter.listen(event)
    player.listen(event)
    text.listen(event)  // e.g.,the text could change color if the mouse is over it,
}

Вопрос

Можно ли определить метод вне области видимости класса через указатель на функцию, которая использует методы указанного класса?Это должно было бы работать для подкласса.Класс Greet и функция greetIfRed фиксируют функциональность, которую я пытаюсь достичь.

1 Ответ

0 голосов
/ 24 октября 2018

Итак, я экспериментировал со многими предложениями, и мне удалось создать рабочий пример без многих изменений.Я скомпилировал это с C ++ 14.

#include <iostream>
#include <functional>

enum Color{ red, green, blue };

class Event {
public:
    void listen(const Color& color) {
        if(callable) callable(color);
    }

    void defineAction( std::function<void(const Color& color)> function) {
        callable = function;
    }

protected:
    std::function<void(const Color& color)> callable = nullptr;
};

class Greeter: public Event {
public:
    void greet() { std::cout << "Hello" << std::endl; }
};

int main()
{
    Greeter greeter;

    greeter.defineAction([&greeter](const Color& color){
        if(color == red)
            greeter.greet();
    });
    greeter.listen(red);
    greeter.listen(green);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...