2017-03-18 25 views
0

多くの小規模なクラスがいくつかのデータをリッスンし、特定のインスタンスでは他のクラスに通知する大きなプロジェクトがあります。だから私はC++リスナー使用時に多重継承を避けるための設計

class Calc {} 

class Spotter {} 

class Updater {} 

.... 

のようなクラスとそれらに耳を傾け、いくつかの他のクラス

class Listener_1 {} 

class Listener_2 {} 

を持っており、プロジェクトでは、多くのインターフェイス

class ICalcListener { 
    virtual void onCalcCall(...) {} 

class ISpotterListener { 
    virtual void on SpotterCall(...) {} 

.... 

になってしまったとリスナーがすべて継承されていませんコールバックを上書きして反応する必要がある場合は、

class Listener_1 : public ICalcListener, public ISpotterListener, ... { 
    virtual void onCalcCall(...) { doThis(); } 
} 

デザインが機能しているが、ここでは最大限に自分自身をインタフェースと継承よりも、これに対処するためのより良い方法がある場合、私は疑問に思って。ほとんど私が必要とするのは、コールバックを登録することだけです。

EDIT: 私はラウンドより突っついたととのインターフェイスを使用する代わりに(私はC11を使用しています)を使用しているようにそれはそう 1)デリゲート 2)のstd ::機能 3)ラムダ関数

パフォーマンスは重要ですが、シンプルさも高く評価されている場合、どのような方法が最適ですか?

+0

http://codereview.stackexchange.com/ –

+0

複数のインターフェイスの継承はそれほど悪くありません。それは多くの問題を提起するデータ継承です。 –

答えて

1

メソッドを持ついくつかの抽象クラスからの多重継承はそれほど悪くなく、うまくいきます。私はそれがあなたが持っているすべてのタイプの通知をサポートするために、たくさんの "不気味な"コードを生成することに同意します。

基本的には、すべてのイベントの抽象クラスがIXXXNotifyよりJavaスタイルです。

私はあなたのプロジェクトがあり、まさに、それは物事を行う方法を知りませんが、あなたはこれらの代替を探してみてください:

  1. スティックINotify抽象クラスに、それはより汎用的にするので、彼らEventのような1つの引数だけがあり、イベントタイプを含むすべての必要な情報を保持します。これにより、インターフェイスクラスの量は少なくなりますが、イベントタイプにはswitchステートメントの追加頭痛が発生します。このアプローチは、あなたのコードの "OOPness"を少し壊します。

  2. 一般的なイベント/メッセージバスを作成します。ここでも、特定のイベントに関心のある一般的なEventパラメータとオブジェクトがあります。訪問者または観察者のパターンを見て、より一般的な方法でそれらを考える。

  3. 「イベントハンドラ」としてstd::functionを使用してください。ここでの欠点は、任意のイベントに1つのハンドラしか割り当てることができないことです。これを解決するには、std::functionの上にレイヤーを追加します。

  4. Qtやブーストのように、すでにこれを処理している既存のライブラリを見てください。

+0

ありがとう、それは素敵な概要です。私はそれらを使うことができないので、ライブラリはオプションではありませんが、他のライブラリは面白そうです。これは、誰もがパターンやデザインを読む上で参考になるようです。 https://sourcemaking.com/ – chrise