Window
にリストされているさまざまなタイプのイベントを伝播するクラスを作成しています
enum Event {WINDOW_ClOSE=0x1, WINDOW_REDRAW=0x2, MOUSE_MOVE=0x4, ...};
ウィンドウで通知登録されているオブジェクトへ。イベントの種類ごとに、通知を許可するためにオブジェクトが拡張する必要がある抽象クラスがあります。たとえば、イベントに反応するために、私のオブジェクトは、によって呼び出されるメソッドを持つMOUSE_MOVE
から継承します。多くのイベントをリッスンすることは、これらのクラスを複数拡張することで組み合わせることができます。これらのクラスはすべて基本クラスから継承されます。オブジェクトを登録するには、私は呼び出しますMouseMoveListener
process_mouse_move_event()
Window
EventListener
void Window::register(EventListener* object, int EventTypes)
{
if(EventTypes&WINDOW_CLOSE)
/* dynamic_cast object to WindowCloseListener*, add to internal list of all
WindowCloseListeners if the cast works, else raise error */
if(EventTypes&MOUSE_MOVE)
/* dynamic_cast object to MouseMoveListener*, add to internal list of all
MouseMoveListeners if the cast works, else raise error */
...
}
これは問題なく動作しますが、私の不満は、それEventListener
が完全に空であり、コードの臭いがすることです。EventListener
完全に削除してイベントの種類ごとに個別に設定することでこれを回避できることはわかっていますが、これによりWindow::register
インターフェイスが不必要に破壊されると思います (特に、以外の方法register
で同じ問題が発生する可能性があるため)。したがって、次のいずれかの答えを探していると思います。
「あなたは今まで通りの方法でそれを続けることができます。なぜなら...」または
「とにかく別々の
Window::register
方法を導入してください。なぜなら...」またはもちろん「あなたはそれをすべて間違っています、あなたはすべきです...」。
編集:
EventListener
Igors コメントのリンクから: 上記のことは、たとえば仮想デストラクタに少なくとも 1 つの仮想メンバーがある場合にのみ機能する ため、クラスは技術的に完全に空ではありません。
編集2:
nmのソリューションを「私はすべて間違っている」タイプの1つとして時期尚早に受け入れました。ただし、これは 2 番目のタイプです。EventListener->register(Window&)
ポリモーフィックに呼び出すことができたとしても、選択的な通知を登録Window
できる非常に冗長なインターフェイス (宣言されたメソッドに関して) を実装する必要があります。EventListeners
これは、上記の代替ソリューションと同等ですが、EventListener
正当な理由なくクラスを追加で導入するだけです。結論として、標準的な答えは次のようです。
似たような関数をたくさん宣言するのを避けるためだけに + 空の基本クラスを実行しないでくださいdynamic_cast
。後でコードを保守するときに問題が発生します。多くの関数を書きます。
編集3:
私にとって満足のいく解決策(テンプレートを使用)を見つけました。空の基本クラスを使用しなくなり、nm によって指摘されたメンテナンスの問題が発生しなくなりました。