9

私は1つのアニメーションクラスを持っています。PlayPauseおよびStopアニメーションのイベントのオブザーバーが必要です。この問題に対して 2 つの解決策を見つけましたが、どちらを選択すればよいかわかりません。

  1. boost::signals などを使用し、すべてのイベントにコールバックを登録します

  2. 3 つの純粋仮想関数 ( OnPlay()OnPause()OnStop()) を持つ単純なインターフェイスを作成し、このインターフェイスを実装する Animation クラス オブジェクトに渡します。

どの方法にも長所と短所があります。これまでに見つけたものを列挙してみます。

1の利点。

  • 任意のメンバー関数/フリー関数をコールバックとして使用できます
  • それらすべてを気にしない場合、3つの関数すべてを実装する必要はありません
  • Animation クラスから追加のパラメーターを渡すことなく、同じオブジェクトを複数のアニメーションのオブザーバーとして使用できます。

1のデメリット。

  • コールバックごとに呼び出し可能なオブジェクトを作成する必要があります
  • 後で新しいイベントを追加したい場合、それが使用された場所を見つけるのは困難です (コンパイラーは、新しいイベントを実装または無視するよう強制できません)。
  • どういうわけか奇妙な構文 (私は std::bind/boost::bind をどこでも使用する必要があります)。

2のメリット。

  • 分かりやすい施工
  • Animation/Observer インターフェース クラスに新しいイベントを追加すると、コンパイラは新しい関数を実装する (おそらく空にする) ように強制します。

2のデメリット。

  • 1つしか使用しない場合でも、3つの関数を実装する必要があります(おそらく空です)
  • アニメーションから追加のパラメーター (ID など) を送信しないと、同じオブジェクトを別のアニメーションのオブザーバーとして使用することはできません。
  • 無料の機能は使用できません。

何を使うべきか教えてください。あなたの経験から、この問題にはどちらが優れていますか?最初のアプローチからの自由か、2番目のアプローチからの明確で理解しやすいコードですか? 両方の方法または他の解決策の他の利点/欠点を教えてください。

4

3 に答える 3

1

最も単純なおもちゃの例を除いて、私の意見では、Boost.Signals2が優れたソリューションになります。適切に設計され、十分にテストされ、十分に文書化されています。車輪の再発明は、宿題のような演習には適していますが、本番コードには適していません。たとえば、独自のオブザーバーをスレッドセーフにすることは、正しく効率的にするのは簡単ではありません。

リストされた欠点について具体的に話し合う

  • 名前付き関数オブジェクトの代わりに、または構文を使用して C++11 ラムダを記述することができboost::bindます (とにかく、ほとんどの使用法ではそれほど複雑ではありません)。
  • 未使用のイベントについてのあなたの主張がよくわかりません。かなり高度な接続管理を実行して、スロットから信号を照会して切断することができます。

TL;DR : Boost.Signals2 に慣れる

于 2013-07-29T14:29:17.293 に答える
0

私は、両方を使用できると思います:)しかし、それはニーズに依存します。この両方のパターンを使用するコードがいくつかあります。onSomething() という関数 (onMouseButton()、onKey()、onDragStart() など) はたくさんありますが、コールバックもあります。何らかの動作を実装する必要があるが、オブジェクトのクラス全体に対して、onSomething() アプローチを使用します。しかし、同じクラスのオブジェクトがたくさんあるが、それらの一部だけが拡張機能を必要とする場合、コールバックは完璧な方法です。

実装では、次のように行われます: onSomething() メソッド (bool を返す) を使用しようとするディスパッチ コードがいくつかあり、その結果が false の場合、コールバックが定義されているかどうかがチェックされ、定義されている場合は実行されます。

于 2013-07-29T12:59:36.833 に答える