Передача указателя на функцию-член в качестве указателя на функцию - PullRequest
5 голосов
/ 21 декабря 2011

Итак, вот ситуация: я использую C ++, SDL и GLConsole вместе.У меня есть класс SDLGame, который имеет Init(), Loop(), Render() и т. Д. - по сути, он содержит логику для моего игрового класса.Пока GLConsole - хорошая библиотека - она ​​позволяет мне определять CVars и тому подобное, даже внутри моего класса SDL.Однако при определении команд я должен указать ConsoleFunc, который typedef'd как

typedef bool (*ConsoleFunc)( std::vector<std::string> *args);

Достаточно просто.Однако, как я уже сказал, все мои функции находятся в моем классе, и я знаю, что не могу передавать функции указателя на класс в качестве аргументов указателя на функцию.Я не могу определить статические функции или создать функции вне моего класса, потому что некоторые из этих ConsoleFuncs должны иметь доступ к членам данных класса, чтобы быть полезными.Я бы хотел, чтобы это было ООП, так как - ну, ООП - это хорошо.

Ну, на самом деле, эта проблема "решена", но она крайне уродлива.У меня просто есть экземпляр SDLGame, объявленный как переменная extern, и я использую его в своем классе ConsoleFuncs / main.

Итак, вопрос: есть ли способ сделать это, который не глуп иглупо нравится, как я это делаю?(В качестве альтернативы: есть ли консольная библиотека, такая как GLConsole, которая поддерживает SDL и может делать то, что я описываю?)

1 Ответ

7 голосов
/ 21 декабря 2011

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

Функция-член нуждается в указателе this для вызова, и если у вас нет способа ее передать, вывам не повезло (я думаю, что указатель std::vector<std::string>* args - это то, что вы передали из библиотеки).

Другими словами, даже если эта библиотека использует контейнеры C ++, она не является хорошей библиотекой C ++, потому что онаполагается на бесплатные функции для обратных вызовов.Хорошая библиотека C ++ будет использовать boost::function или что-то подобное, или по крайней мере позволит вам передать указатель void* user_data, который передается в ваш обратный вызов.Если бы у вас было это, вы могли бы передать указатель this вашего класса, привести его обратно к обратному вызову и вызвать соответствующую функцию-член.

...