Was ich bisher habe, ist:weak_ptr Mit dem Observer-Muster zu implementieren
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();
}
}
}
(de/Konstrukteuren werden hier umgesetzt, aber leer , also habe ich sie weggelassen)
Worauf ich mich festhalte ist, wie man das Abbestellen-Verfahren implementiert. Ich stieß auf das Erase - Remove - End - Idiom, aber ich verstehe, dass es nicht "out of the box" funktionieren wird, wie ich mein Observable eingerichtet habe. Wie prüfe ich die weak_ptr-Elemente im Beobachtervektor, damit ich den gewünschten Observer entfernen kann?
Ich bin auch auf der Suche nach einem Ratschlag, wie der Parametertyp für meine Un/Subscribe-Verfahren sein sollte. Wäre es besser, std::shared_ptr<Observer>&
oder const std::shared_ptr<Observer>&
zu verwenden, da wir es nicht ändern werden?
Ich möchte wirklich Observables nicht besitzen ihre Beobachter, wie es scheint, um die Absichten des Musters zu verraten, und ist sicherlich nicht, wie ich den Rest des Projekts, das letztlich das Muster nutzen wird strukturieren will . Das heißt, eine zusätzliche Ebene der Sicherheit/Automatisierung, die ich in Betracht ziehe, ist, dass Beobachter einen Spiegelvektor von weak_ptr speichern. Ein Observer auf seinem Weg nach draußen konnte sich dann von allen Observablen, die er abonniert hatte, abmelden, und ein Observable auf seinem Weg nach draußen konnte den Rückbezug auf sich selbst von jedem der beobachtenden Beobachter löschen. Offensichtlich wären die beiden Klassen in einem solchen Szenario Freunde.
Beachten Sie, dass 'std :: remove_if' ** nicht ** die Elemente aus dem Container entfernt. Sie müssen 'container.erase' mit verwenden. Suche nach Löschen-Entfernen-Idiom. – Nawaz
... obwohl in diesem Fall 'std :: remove_if' (wahrscheinlich) ineffizient wäre; 'std :: find_if' zusammen mit' .erase' würde besser (oder mindestens * semantisch * korrekt) funktionieren. – Nawaz
Hinzugefügt wptr.expired() überprüfen Sie auf Sicherheit und um tote Beobachter zu entfernen. – M2tM