2011-12-21 14 views
5

Oto sytuacja: używam C++, SDL i GLConsole w połączeniu. Mam klasę, SDLGame, która ma Init(), Loop(), Render() itd. - zasadniczo zawiera logikę dla mojej klasy gry.
GLConsole jest do tej pory przyjemną biblioteką - pozwala mi definiować CVary i takie, nawet w mojej klasie SDL. Jednak podczas definiowania poleceń, muszę określić ConsoleFunc, który jest typedef'd jakPrzekazywanie funkcji wskaźnika do elementu jako wskaźnika do funkcji

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

dość proste. Jednakże, jak już powiedziałem, moje funkcje są w mojej klasie, i wiem, że nie mogę przekazywać funkcji typu wskaźnik-do-klasy jako argumentów wskaźnik-funkcja. Nie mogę zdefiniować funkcji statycznych ani funkcji poza moją klasą, ponieważ niektóre z tych ConsoleFuncs muszą mieć dostęp do elementów danych klas, aby były użyteczne. Chciałbym zachować OOP, ponieważ - no cóż, OOP jest miłe.

Cóż, faktycznie mam ten problem "rozwiązany" - ale jest wyjątkowo brzydki. Mam tylko wystąpienie SDLGame zadeklarowane jako zmienna extern i użyj tego w moim ConsoleFuncs/main klasy.

Pytanie brzmi: Czy istnieje sposób, aby to zrobić, nie jest głupi i głupi, tak jak ja to robię? (Alternatywnie: czy istnieje biblioteka konsolowa, taka jak GLConsole, która obsługuje SDL i może robić to, co opisuję?)

Odpowiedz

7

Jeśli jedynym interfejsem, który posiadasz jest wskaźnik funkcji, to jesteś wkręcony.

Funkcja członkowska wymaga wywołania wskaźnika this, a jeśli nie masz możliwości, aby go przekazać, nie masz szczęścia (domyślam się, że wskaźnik std::vector<std::string>* args jest tym, co dostajesz z biblioteki).

Innymi słowy, nawet jeśli ta biblioteka używa kontenerów C++, nie jest to dobra biblioteka C++, ponieważ opiera się na darmowych funkcjach wywołań zwrotnych. Dobra biblioteka C++ używałaby boost::function lub czegoś podobnego, lub by co najmniej pozwoliłoby na przekazanie wskaźnika void* user_data do twojego wywołania zwrotnego. Jeśli tak, możesz przekazać wskaźnik klasy, odrzucić go z powrotem w callback i wywołać odpowiednią funkcję członka.

+0

Dobrze dang. Dzięki i tak. Masz jakieś sugestie dotyczące innej biblioteki do użycia? Patrzyłem na OGLConsole, ale ma dokładnie ten sam problem. – Chaosed0

+0

@user: Przepraszamy, brak sugestii biblioteki. :/ – Xeo

+0

Gorąco polecam użycie "void *" "danych użytkownika". Oczywiście, nie jest tak piękny jak delegat nowoczesnego języka, ale jest to bezpieczna ścieżka, ponieważ jest to kod, który rejestruje wywołanie zwrotne i dane użytkownika jako parę. Tak więc jest w 100% bezpieczne, aby po prostu rzucić przychodzące 'void *' do odpowiedniego typu klasy, ponieważ wywołanie zwrotne jest ustawione z myślą o tym celu. – TheBuzzSaw

Powiązane problemy