2011-12-21 40 views
5

Así que aquí está la situación: estoy usando C++, SDL y GLConsole conjuntamente. Tengo una clase, SDLGame, que tiene el Init(), Loop(), Render() etc., esencialmente, tiene la lógica para mi clase de juego.
GLConsole es una buena biblioteca hasta ahora; me permite definir CVars y demás, incluso dentro de mi clase SDL. Sin embargo, al definir comandos, tengo que especificar un ConsoleFunc, que se typedef'd comoPasar la función puntero a miembro como puntero a función

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

lo suficientemente simple. Sin embargo, como dije, mis funciones son todas en mi clase, y sé que no puedo pasar las funciones de puntero a clase como argumentos de puntero a función. No puedo definir funciones estáticas ni realizar funciones fuera de mi clase porque algunos de estos ConsoleFuncs deben acceder a los miembros de datos de clase para que sean útiles. Me gustaría mantenerlo como OOP, ya que, bueno, OOP es bueno.

Bueno, en realidad tengo este problema "resuelto", pero es extremadamente feo. Solo tengo una instancia de SDLGame declarada como una variable externa, y la utilizo en mi ConsoleFuncs/clase principal.

Entonces, la pregunta es: ¿Hay alguna manera de hacer esto que no sea estúpida y tonta como la forma en que lo estoy haciendo? (Alternativamente: ¿hay una biblioteca de consola como GLConsole que admita SDL y pueda hacer lo que estoy describiendo?)

Respuesta

7

Si la única interfaz que tiene es ese puntero a la función, entonces está jodido.

Una función miembro necesita un puntero this a ser llamado, y si usted no tiene manera de pasar de eso, usted está fuera de suerte (supongo que el puntero std::vector<std::string>* args es lo que obtienes pasado de la biblioteca).

En otras palabras, aunque esa biblioteca utiliza contenedores C++, no es una buena biblioteca C++, ya que depende de funciones gratuitas para devoluciones de llamadas. Una buena biblioteca de C++ usaría boost::function o algo similar, o sería como mínimo le permitía pasar un puntero void* user_data que pasa a su devolución de llamada. Si tuviera eso, podría pasar el puntero this de su clase, devolverlo dentro de la devolución de llamada y llamar a la función miembro correspondiente.

+0

Bien, dang. Gracias de cualquier manera. ¿Tienes alguna sugerencia para utilizar otra biblioteca? Estaba mirando OGLConsole, pero tiene exactamente el mismo problema. – Chaosed0

+0

@usuario: Lo sentimos, no hay sugerencia de biblioteca. :/ – Xeo

+0

Recomiendo encarecidamente el uso de un 'void *' "datos de usuario". Claro, no es tan bonito como un 'delegado' moderno de idiomas, pero es una ruta segura de tomar ya que es su código el que registra la devolución de llamada y los datos del usuario como un par. Entonces, es 100% seguro lanzar el 'void *' entrante al tipo de clase apropiado porque la devolución de llamada se establece con ese propósito en mente. – TheBuzzSaw

Cuestiones relacionadas