2011-12-21 6 views
5

Итак, вот что: я использую 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 и может делать то, что я описываю?)

ответ

7

Если только у вас есть интерфейс, то вы будете ввернуты.

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

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

+0

Well dang. Спасибо, в любом случае. Есть предложения по использованию другой библиотеки? Я смотрел на OGLConsole, но у него такая же проблема. – Chaosed0

+0

@user: Извините, никаких предложений библиотеки. :/ – Xeo

+0

Я настоятельно рекомендую использовать пользовательские данные 'void *' '. Конечно, это не так хорошо, как современный делегат языка, но это безопасный путь, потому что именно ваш код регистрирует обратный вызов и пользовательские данные как пару. Таким образом, на 100% безопасно просто вводить входящий 'void *' в соответствующий тип класса, потому что обратный вызов задается с учетом этого намерения. – TheBuzzSaw