Я создаю приложение спирографа, и у меня есть простой класс GUI, который производит и управляет кнопками - вы можете вызывать эти функции с помощью указателя пользовательской функции после нажатия на них.
У меня также есть Класс двигателя, который управляет рисованием моего спирографа и кнопок GUI.
Я хотел бы создать кнопку с указателем на функцию-член из класса движка, но я получаю сообщение об ошибке.
Ошибка возникает, когда я пытаюсь создать кнопка с указателем на функцию из класса Engine.
Вот в двух словах проблема, предложенная Фрэнком в комментариях (спасибо)
class Engine;
typedef void(Engine::*enginefunc)(void);
class Engine
{
void cb();
void register_callback(enginefunc ptr);
void foo() {
register_callback(cb);
}
};
Вот мой класс двигателя:
Engine.h
class Engine : public GUI
{
private:
//....
public:
Engine(sf::Vector2f* mousepos);
//...
//...inherited a function from GUI called addbutton.
};
Engine::Engine(sf::Vector2f* mousepos)
:GUI(mousepos)
{
//THIS IS THE LINE WHICH PRODUCES THE ERROR. I AM TRYING TO PASS THE CHANGE POINT FUNCTION INTO THE GUI BUTTON.
addbutton(sf::Vector2f{ 100,50 }, sf::Vector2f{ 200,100 }, "Button", sf::Color::Red, sf::Color::Blue, changepoint);
}
Вот GUI .h (Содержит функцию addbutton, которая вызывает ошибку)
class Engine;
typedef void(Engine::* enginefunc)(void);
class GUI : public sf::Drawable
{
private:
//...
public:
GUI(sf::Vector2f* mousepos);
void addbutton(const sf::Vector2f& position, const sf::Vector2f& dimension, const std::string& text, sf::Color initcolor, sf::Color highlightcolor, enginefunc ptr);
//other member funcs..
};
Вот GUI :: функция addbutton
void GUI::addbutton(const sf::Vector2f& pos, const sf::Vector2f& size, const std::string& text, sf::Color before, sf::Color after, enginefunc ptr)
{
buttons.emplace_back(pos, size, text, before, after, ptr);
}
Итак, функция addbutton создает класс GUIButton, в котором хранится функция ptr. Когда кнопка нажата, указатель этой функции вызывается через std :: invoke.
Вот мой GUIButton.h
class Engine;
typedef void(Engine::*enginefunc)(void);
class GUIButton : public sf::RectangleShape
{
public:
GUIButton(const sf::Vector2f& position, const sf::Vector2f& size, const std::string& text, sf::Color initcolor, sf::Color highlightcolor, enginefunc ptr);
void action(Engine& e);
//other members...
private:
//other members...
enginefunc actionptr;
};
Как вы можете видеть, enginefun c GUIButton: : actionptr - это указатель на функцию, который будет действовать при нажатии кнопки.
Вот функция GUIButton :: action (), которая вызывает функцию:
void GUIButton::action(Engine& e)
{
if (actionptr != nullptr)
{
std::invoke(actionptr, e);
}
}
Я не понимаю что я делаю не так Я понимаю, что указатель на функцию-член должен быть привязан к конкретному объекту c, поэтому я взял объект Engine в качестве ссылки.
Есть предложения?