Ist das Observer-Entwurfsmuster bereits in STL definiert (wie java.util.Observer und java.util.Observable in Java)?Observer-Entwurfsmuster in C++
Antwort
Hier ist eine Referenzimplementierung (von Wikipedia).
#include <iostream>
#include <string>
#include <map>
#include <boost/foreach.hpp>
class SupervisedString;
class IObserver{
public:
virtual void handleEvent(const SupervisedString&) = 0;
};
class SupervisedString{ // Observable class
std::string _str;
std::map<IObserver* const, IObserver* const> _observers;
typedef std::map<IObserver* const, IObserver* const>::value_type item;
void _Notify(){
BOOST_FOREACH(item iter, _observers){
iter.second->handleEvent(*this);
}
}
public:
void add(IObserver& ref){
_observers.insert(item(&ref, &ref));
}
void remove(IObserver& ref){
_observers.erase(&ref);
}
const std::string& get() const{
return _str;
}
void reset(std::string str){
_str = str;
_Notify();
}
};
class Reflector: public IObserver{ // Prints the observed string into std::cout
public:
virtual void handleEvent(const SupervisedString& ref){
std::cout<<ref.get()<<std::endl;
}
};
class Counter: public IObserver{ // Prints the length of observed string into std::cout
virtual void handleEvent(const SupervisedString& ref){
std::cout<<"length = "<<ref.get().length()<<std::endl;
}
};
int main(){
SupervisedString str;
Reflector refl;
Counter cnt;
str.add(refl);
str.reset("Hello, World!");
std::cout<<std::endl;
str.remove(refl);
str.add (cnt);
str.reset("World, Hello!");
std::cout<<std::endl;
return 0;
}
Es ist schwer, eine C++ - Implementierung ernst zu nehmen, die ungültige Mitgliedsfunktionsnamen wie _Notify verwendet. –
Es ist immer noch gültig C++. –
Offenbar hat es auch andere Probleme. Überprüfen Sie die Diskussionsseite: http://en.wikipedia.org/wiki/Talk:Observer_pattern#Implementation_flaw_in_C.2B.2B – Manuel
Nein, tut es nicht. Die C++ STL ist viel kleiner als die Standardbibliothek von Java. Wenn Sie nach etwas suchen, um die STL zu erweitern, die von fast allem unterstützt wird, sollten Sie sich die Boost-Bibliotheken ansehen. In diesem Fall sollten Sie sich Boost.Signals ansehen, das ein Signal/Slot-Modell bereitstellt.
Nein, aber Boost.Signals2 gibt Ihnen etwas Ähnliches.
Die Observer design pattern ist in der STL
nicht definiert. Sie können auf die "Gang of four" Design Patterns book verweisen oder eine Google-Suche sollte genügend Details zur Verfügung stellen, um es zu implementieren. Wenn diese Frage nicht bald beantwortet wird, werde ich ein schnelles Beispiel veröffentlichen.
Oder Sie können die Wikipedia-Implementierung, die jemand in einer anderen Antwort verknüpft hat, kopieren und einfügen – Manuel
danke! Boost-Signale sehen interessant aus.Ich habe Boost für Zufallszahlengenerierung verwendet, aber nie für ein Beobachtermuster oder Signale, wie sie es nennen. Wie auch immer, ich denke, das GOF-Beobachtermuster und Boost-Signale zu bewerten, ist zumindest für akademische Zwecke eine gute Idee. –
Soweit mein Wissen in C++ geht, hat STL keine Implementierung für Observer-Muster. Es gab jedoch einen Vorschlag für Signal/Slot für die Standardbibliothek in TR2.
Es gibt viele Bibliotheken, die Implementierung für Observer-Muster Qt-Bibliothek als einer der Pioniere bietet. Die Boost-Bibliothek hat eine Implementierung (siehe Boost :: Signale & Boost :: Signals2).
Die Poco C++ - Bibliothek verfügt über eine übersichtliche Implementierung des Beobachtermusters (siehe NotificationCenter).
libsigC++, cpp-events sind einige der anderen Bibliotheken, die Signal/Slot-Implementierungen bereitstellen.
#include <iostream>
#include <string>
#include <set>
using namespace std;
class Subject;
class Observer {
public:
virtual void update(Subject & subject) = 0;
};
// also knows as Observable in literature
class Subject
{
string state;
set<Observer*> observers;
public:
void attachObserver(Observer *o) { observers.insert(o); }
void detachObserver(Observer *o) { observers.erase(o); }
void notifyObservers()
{
for (auto &o : observers)
{
o->update(*this);
}
}
string getState() { return state; }
void changeState(const string & s)
{
state = s;
notifyObservers();
}
};
class ObserverImpl : public Observer
{
string state;
public:
void update(Subject & sbj) override
{
state = sbj.getState();
}
string getState() { return state; }
};
int main()
{
ObserverImpl a, b, c;
Subject subject;
subject.attachObserver(&a);
subject.attachObserver(&b);
subject.attachObserver(&c);
subject.changeState("Observer pattern");
cout << a.getState() << endl;
cout << b.getState() << endl;
cout << c.getState() << endl;
return 0;
}
siehe auch UML/Flussdiagramme http://www.patterns.pl/observer.html
- 1. Matlab in C C++ und C C++ in Matlab
- 2. Testcode in C C++
- 3. C++ Union in C#
- 4. Convert C++ in C
- 5. C/C++ in Android?
- 6. virtuelle Datei? in c/C++ oder C#
- 7. main() in C, C++, Java, C#
- 8. Einführung in C# für C/C++ - Benutzer
- 9. statisches Array in C# vs C/C++
- 10. Externe C/C++ - Bibliothek nicht in C#
- 11. C++ - Klasse in C++ DLL in C# Windows Forms Klasse
- 12. Funktionsdeklaration in C und C++
- 13. Funktionale Programmierung in C/C++?
- 14. String-Operator in C/C++
- 15. Convert C++ struct in C#
- 16. Convert C# RSACryptoServiceProvider in C++
- 17. Call C++ - Bibliothek in C#
- 18. Robuste Gesichtserkennung in C/C++?
- 19. Mathematik in C/C++ - Rundungsfrage
- 20. lange lange in C/C++
- 21. mit scanf in C/C++
- 22. Aufruf C# DLL in C++
- 23. C Komplexe Zahlen in C++?
- 24. #define Verwendung in C/C++
- 25. Numerische Konvertierung in C/C++
- 26. C-String Vergleichsproblem in C++
- 27. Kompiliere C# in objective-C
- 28. (c = getchar())! = EOF in C#?
- 29. Quaternion-Bibliotheken in C/C++
- 30. Referenzieren/Dereferenzieren in C/C++
Vermutlich als ein Beispiel eines anderen Standard-Bibliothek der Sprache, die die Beobachter-Muster hinein gebaut hat. –
ja Jeremy, das ist korrekt – Lucas
Ist Boost akzeptabel für Sie? Wenn nicht, wäre ich bereit, eine Standard-Nicht-Boost-Implementierung zu veröffentlichen. –