を実装するためのweak_ptrを使用することです:私がこれまで持って何Observerパターン
Observer.h
class Observer
{
public:
~Observer();
virtual void Notify() = 0;
protected:
Observer();
};
class Observable
{
public:
~Observable();
void Subscribe(std::shared_ptr<Observer> observer);
void Unsubscribe(std::shared_ptr<Observer> observer);
void Notify();
protected:
Observable();
private:
std::vector<std::weak_ptr<Observer>> observers;
};
Observer.cpp
void Observable::Subscribe(std::shared_ptr<Observer> observer)
{
observers.push_back(observer);
}
void Observable::Unsubscribe(std::shared_ptr<Observer> observer)
{
???
}
void Observable::Notify()
{
for (auto wptr : observers)
{
if (!wptr.expired())
{
auto observer = wptr.lock();
observer->Notify();
}
}
}
(デ/コンストラクタはここで実装されているが、空、私はそれらを残しました)
私が立ち往生しているのは、購読解除の手順を実装する方法です。私は、イレーズ・エキストラ・イディオムを見つけましたが、Observableをどのようにセットアップしたかで「すぐに使える」ことは理解できません。オブザーバーベクトルのweak_ptr要素を調べて、オブザーバーを削除できるようにするにはどうすればよいですか?
また、Un/Subscribeプロシージャのパラメータタイプについていくつかのアドバイスを探しています。 std::shared_ptr<Observer>&
またはconst std::shared_ptr<Observer>&
を使用する方が良いでしょうか?私たちはそれを変更しないでしょうか?
ObservablesにObservidersを所有させたくないのは、パターンの意図を裏切っているようですが、最終的にパターンを利用する残りのプロジェクトをどのように構造化したいのかは確かです。つまり、私が検討しているセキュリティ/オートメーションの追加層は、Observersにweak_ptrのミラーベクトルを保存させることです。その後、オブザーバーは、加入していたObservableからすべて退会することができ、Observableは退出時にObservableを観察している各オブザーバーからバックリファレンスを消去することができます。明らかに、2つのクラスはこのようなシナリオでは友人になるでしょう。
注意: 'std :: remove_if'は、要素をコンテナから削除しません。それと一緒に 'container.erase'を使う必要があります。削除イディオムを検索します。 – Nawaz
...この場合、 'std :: remove_if'は(おそらく)非効率的です。 'std :: find_if'と' .erase'はより良く(あるいは少なくとも*意味的に*正しい)実行されます。 – Nawaz
wptr.expired()を追加して安全性をチェックし、死んだオブザーバを削除します。 – M2tM