-2

C++ で単純なゲームの関数ポインターを使用して単純なイベント インターフェイスを実装したいと考えています。これは、allegro lib のイベント インターフェイスを改善するために行われます。したがって、次のコードを作成しましたが、機能しません。

typedef void (*event_handler)(int); //type for the event handler
const int TESTKEY_A = 1; // example Key as event arg

class Game
{
      private:
              bool is_running ;
      protected:
               event_handler on_key_down[2];
      public:
               void run();
               void do_events(int e) ;
               void stop() {is_running = false;}
};
void Game::run()
{
    is_running=true; 
    while(is_running) 
        do_events(1);
}

void Game::do_events(int e) 
{
    if(e==1) 
    {
        for(int i = 0; i < 2 ;i++)
            on_key_down[i](TESTKEY_A);
    }
}

class Pong_Game : public Game
{
      public:
               Pong_Game();
               void On_Key_Down_Player1(int key) { return;}
               void On_Key_Down_Player2(int key) { return;}
};

Pong_Game::Pong_Game()
{
    on_key_down[0] = &this->On_Key_Down_Player1;
    on_key_down[1] = &this->On_Key_Down_Player2;
}

int main()
{
    Game *my_game = new Pong_Game();
    my_game->run();
    return 0;
}

コンパイラ ログ:

Compiler: Default compiler
Executing  g++.exe...
g++.exe "U:\Eigene Dateien\eventhandler.cpp" -o "U:\Eigene Dateien\eventhandler.exe"    -I"C:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include"  -I"C:\Dev-Cpp\include\c++\3.4.2\backward"  -I"C:\Dev-Cpp\include\c++\3.4.2\mingw32"  -I"C:\Dev-Cpp\include\c++\3.4.2"  -I"C:\Dev-Cpp\include"   -L"C:\Dev-Cpp\lib" 
U:\Eigene Dateien\eventhandler.cpp: In constructor `Pong_Game::Pong_Game()':
U:\Eigene Dateien\eventhandler.cpp:45: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say `&Pong_Game::On_Key_Down_Player1'
U:\Eigene Dateien\eventhandler.cpp:45: error: cannot convert `void (Pong_Game::*)(int)' to `void (*)(int)' in assignment
U:\Eigene Dateien\eventhandler.cpp:46: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say `&Pong_Game::On_Key_Down_Player2'
U:\Eigene Dateien\eventhandler.cpp:46: error: cannot convert `void (Pong_Game::*)(int)' to `void (*)(int)' in assignment

Execution terminated

編集: - コードを変更 - コンパイラログを追加

ありがとうございました!

4

1 に答える 1

1
  1. 「プレーン」関数ポインターを初期化するためにメンバー関数を使用しています。T *thisメンバー関数は、関数と共に渡される隠しオブジェクトがあるという点で、「プレーンな」関数とは異なります。
  2. これは、関数ポインターを使用するよりも、継承によって実装された「イベントハンドラー」インターフェイスを使用することで、はるかにうまく解決できるようです。

このようなもの:

class Game
{
    private:
        bool is_running ;
    public:
        void run(){is_running=true; while(is_running) do_events(1);}
        void do_events(int e) {if(e==1) On_Key_Down(TESTKEY_A);}
        void stop() {is_running = false;}

        virtual void On_Key_Down(int key) = 0;
        ... other event handlers here ... 
};

class Pong_Game : public Game
{
    public:
        void Pong_Game() {}
        void On_Key_Down(int key) { // handle key event...}
        ... other event handlers here ... 
};

コメントによると: 複数のプレーヤーをカバーするには、「プレーヤーごとのイベント処理」を実装することをお勧めします。

class Player 
{
  public:
    enum moves { move_up, 
                 move_down, 
                 move_left, 
                 move_right, 
                 move_jump, 
                 move_shoot, ...  }; 

    ... 
    virtual void On_Key_Down(int key) = 0;
    ... 
};

class Player_A
{
   public:
    ...
    virtual moves On_Key_Down(int key) { if (key == 'W') return move_up;  ...  }
}

class Player_B
{
   public:
    ...
    virtual moves On_Key_Down(int key) { if (key == 'I') return move_up;  ...  }
}


class Pong_Game : public Game
{
    private:
        vector<Player *> players;
    public:

        void Pong_Game() {}
        void On_Key_Down(int key) 
        { 
           for(p : players) {
               Player::moves m =  p->On_key_down(); 
               ...  
            }
        }
        ... other event handlers here ... 
};

(これは簡単にハッキングされたものです - 「移動」はおそらく別の場所に配置する方が適切である可能性があり、正確な構造は「私が今考えられるもの」にすぎません - おそらくclass Player_A_Pong : public Player_A、「プレーヤー A のラケットはここにあり、プレーヤー B のラケットはここにあります..." - おそらく他の対処方法もあるでしょう)。

于 2013-06-11T09:21:11.353 に答える