2016-05-18 6 views
0

私は、さまざまなイベントを持つシンプルなイベントシステムを作成しようとしています。だから、私はあなたが関数を登録し、正しいタイプのイベントを受け取り、ブール値を返すことを可能にするイベントクラスを作成しようとしました。それが含まれるクラスと同じタイプのリスト

は、私が欲しいのはEventの任意のサブクラスのメソッドpostEventではなく、そのサブクラスがかかりますし、各サブクラス内のリストlistenersの関数は正しいサブクラスの種類を取るべきであるということです。ここでは、正しいイベント型にキャストする関数を強制的に私が既に持っているコードは、です:

events.h:

namespace events { 
    class Event { 
     public: 
      static const std::List<bool (*)(Event)> listeners; 
      void post(Event event); 
    } 

    class ExampleEvent : Event { 
     int eventData; 
    } 
} 

events.cpp:

namespace events { 
    void Event::post(Event event) { 
     for(int i = 0; i < listeners.size(); i++) { 
      if(listeners[i](event)) return; 
     } 
    } 
} 

されていますサブクラス化されたイベントで次のようなことをすることなく動作させることができます。

bool handleExample(Event event) { 
    ExampleEvent exampleEvent = (ExampleEvent)event; 
    std::cout << exampleEvent.eventData << std::endl; 
    return false; 
} 

// Somewhere else in the code 
ExampleEvent::listeners.push_back(&handleExample); 

私は間違ったコードについてお詫び申し上げますが、私はまだ完全な言語のルールを持っていません。

+1

あなたは仮想関数せずに、派生クラスを持っている場合、あなたは間違ってそれをやっています。 –

+0

@ n.m。私はむしろ仮想関数を持つ派生クラスがない場合は、間違っていると言うだろう。単一クラスは、基本クラスで実装されたデフォルトの動作を使用できます。 – davidhigh

答えて

0

一般的な方法はCRTPを使用することです:ちょうど仮想関数を使用

namespace events { 
    template<typename Derived> 
    class Event { 
     public: 
      static const std::list<bool (*)(Derived)> listeners; 
      void post(Derived event) 
      { 
       static_cast<Derived&>(*this).post(event); 
      } 
    }; 

    class ExampleEvent : Event<ExampleEvent> { 
     int eventData; 
     void post(ExampleEvent event) 
     { 
      //implement post 
     } 
    }; 
} 
0

を:

namespace events { 
    class EventHandler { 
     public: 
      static const std::list<Event*> listeners; 
      void post() { 
       for (Event * listener : listeners) { 
        if (listener->post()) break; 
       } 
      } 
    }; 

    class BaseEvent { 
    public: 
     virtual bool post() = 0; 
     virtual ~BaseEvent() {} 
    }; 

    class ExampleEvent : public BaseEvent { // use public inheritance 
     int eventData; 
    public: 
     virtual bool post() override { 
      if (eventData == 0) return true; 
      return false; 
     } 
    }; 
} 
+0

それは明らかではないかもしれませんが、考えられるのは、postが呼び出されるときに各リスナー関数が呼び出されるということです。したがって、イベントを発生させた場合、そのイベントクラスのすべてのリスナーに通知されます(trueを返すことでイベントをキャンセルしない限り)。 –

+0

@SamM EventHandlerをイベントのリストで使用し、EventHandlerでリストを反復してポストをバーチャルに呼び出すのはなぜですか? –

関連する問題