2011-12-21 30 views
5

ここに状況があります:私はC++、SDL、GLConsoleを併用しています。私はクラスSDLGameInit()Loop()Render()などを持っています - 本質的に、私のゲームクラスのロジックを保持しています。
GLConsoleはこれまでの素晴らしいライブラリです。私のSDLクラスの中でさえ、CVarsなどを定義できます。コマンドを定義するときしかし、私は十分にシンプル関数へのポインタとしてのメンバ関数へのポインタの受け渡し

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

としてtypedefされConsoleFuncを、指定する必要があります。しかし、私が言ったように、私の関数はすべて私のクラスにあり、関数へのポインタとしてクラスへのポインタを渡すことはできません。静的関数を定義したり、クラス外の関数を作成することはできません。これらのConsoleFuncの中には、クラスデータメンバーにアクセスする必要があるものがあります。私はそれをOOPにしておきたいと思います - OOPはいいです

実際、この問題は「解決済み」ですが、非常に醜いです。私はただSDLGameのインスタンスをextern変数として宣言し、それを私のConsoleFuncs/mainクラスで使用しています。

質問:これを行う方法は、私がそれをやっているようにばかばかしくて、ばかなことではないのですか? (あるいは、SDLをサポートするGLConsoleのようなコンソールライブラリがあり、私が何を記述しているのかが分かります)

答えて

7

あなたが持っているインターフェイスが関数ポインタだけであれば、あなたはうんざりです。

メンバー関数にはthisポインタが呼び出されていなければなりません。それを渡す方法がない場合は、運が悪いです(std::vector<std::string>* argsポインターがライブラリから渡されるものと思われます)。

つまり、そのライブラリはC++コンテナを使用していますが、それはコールバックのための自由な関数に依存しているため、良いC++ライブラリではありません。よいC++ライブラリは、boost::functionまたはこれに類するものを使用するか、少なくともでになり、コールバックに渡されるポインタvoid* user_dataを渡すことができます。もしあなたがそれを持っていれば、クラスのポインタを渡し、コールバックの中にキャストし直して、適切なメンバ関数を呼び出すことができます。

+0

ウェルドン。とにかくありがとう。別のライブラリを使用するための提案はありますか?私はOGLConsoleを見ていましたが、まったく同じ問題があります。 – Chaosed0

+0

@user:申し訳ありませんが、ライブラリの提案はありません。 :/ – Xeo

+0

"void *" "ユーザーデータ"の使用を強くお勧めします。確かに、それは現代的な言語の「デリゲート」ほどではありませんが、コールバックとユーザーデータをペアとして登録するコードなので、安全な方法です。コールバックがその意図を念頭に置いて設定されているので、入ってくる 'void * 'を適切なクラス型にキャストするだけで100%安全です。 – TheBuzzSaw

関連する問題