4

社内の別のグループ (C++ で記述) が提供するサード パーティ製ライブラリを使用して、この問題に遭遇しました。

Observer のデストラクタでは、サブスクライブしているすべてのオブザーバブルから切り離されます。この部分は私には理にかなっています。しかし、Observable のデストラクタでは、Observable にまだサブスクライバ リストにあるオブザーバがあるかどうかをチェックします。その場合、エラーをスローします。

デストラクタで意図的にエラーをスローするという事実は脇に置いておきます。オブザーバブルがオブザーバーがそれ自体より長生きしないことを期待すべきではない理由を誰かが私に説明しようとすることができますか、それともこれは単に悪い設計なのですか。これが悪い設計である場合、オブザーバーがオブザーバブルよりも長生きする状況にある場合、それを処理する良い方法はありますか?

4

4 に答える 4

6

Observer に Observable へのポインタ (または参照) があり、Observable が破棄された場合、そのポインタは無効になります。作者はぶら下がっている参照を避けようとしているだけです。

通常の解決策は 3 つあると思います。

1 つは、デストラクタで例外をスローするのではなく、おそらく abort() を呼び出して、このコードが行うことを正確に行うことです。

もう 1 つの方法は、Observable のデストラクタを Observer から登録解除することです。

最後の方法は、「スマート ポインター」 (例: 参照カウントshared_ptr) を使用して、Observable がどの Observer よりも長生きすることを保証することです。

于 2011-09-23T14:59:20.607 に答える
0

それは文脈に依存します。オブザーバー パターンの完全に汎用的な実装では、少なくともオプションで、監視対象オブジェクトの削除をサポートすることを期待していますが、これが意味をなさない用途が多くあり、おそらくプログラミング エラーです。一般に、オブザーバブルが完全に破棄される前に、破棄するという事実をオブザーバーに通知する必要があります。その後、登録を解除する必要があります。つまり、監視可能なレジストリ オブジェクトのデストラクタが呼び出されるまでに、登録済みのオブザーバが存在しないはずです。

于 2011-09-23T14:59:53.060 に答える
0

私は通常、パターンを逆に実装しました。Observable は自分自身を追加し、Observer のリストから自分自身を取り除きます。私のオブザーバーは、アプリケーションの存続期間全体を通じて存続し、オブザーバブルは通常、数秒間存続します。

于 2011-09-23T15:03:40.850 に答える
-1

それは単なる悪い設計であり、オブザーバブルがすべてのオブザーバーよりも長生きすることを保証するものは何もありません。

オブザーバブルのデストラクタにアクセスできる場合は、残りのすべてのオブザーバをデタッチするように書き直してください。

于 2011-09-24T16:42:16.563 に答える