C++中的观察者设计模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2225162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Observer design pattern in C++
提问by Lucas
Is the observer design pattern already defined in STL (Like the java.util.Observer and java.util.Observable in Java) ?
观察者设计模式是否已经在 STL 中定义(如 Java 中的 java.util.Observer 和 java.util.Observable)?
采纳答案by Hogan
Here is a reference implementation (from Wikipedia).
这是一个参考实现(来自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;
}
回答by David Seiler
No, but Boost.Signals2gives you something similar.
不,但是Boost.Signals2给了你类似的东西。
回答by agupta666
As far as my knowledge goes in C++, STL doesn't have an implementation for Observer pattern. There was a proposal for Signal/Slot for standard library in TR2 though.
就我对 C++ 的了解,STL 没有观察者模式的实现。不过,在 TR2 中有一个关于标准库的 Signal/Slot 的提议。
There are plenty of libraries which provides implementation for Observer pattern Qt library being one of the pioneers. The boost library has an implementation (see Boost::Signals & Boost::Signals2).
有很多库提供了观察者模式的实现,Qt 库是先驱者之一。boost 库有一个实现(参见 Boost::Signals & Boost::Signals2)。
The Poco C++ library has a neat implementation of the observer pattern (see NotificationCenter).
Poco C++ 库有一个简洁的观察者模式实现(参见通知中心)。
libsigc++, cpp-events are some of the other libraries that provide signal/slot implementations.
libsigc++、cpp-events 是其他一些提供信号/插槽实现的库。
回答by Yacoby
No it doesn't. The C++ STL is much smaller than Java's Standard Library. If you are looking for something to expand on the STL that is supported by almost everything, it would be worth taking a look at the Boost libraries. In this case you may want to look at Boost.Signalswhich provides a signal/slot model.
不,它没有。C++ STL 比 Java 的标准库小得多。如果您正在寻找可以扩展几乎所有东西都支持的 STL 的东西,那么看看 Boost 库是值得的。在这种情况下,您可能需要查看提供信号/槽模型的Boost.Signals。
回答by Pawe? Dereń
#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;
}
please also see UML/flow diagrams http://codepatterns.ddns.net/
另请参阅 UML/流程图http://codepatterns.ddns.net/
回答by Athens Holloway
The Observer design patternis not defined in the STL
. You can refer to the "Gang of four" Design Patterns bookor a Google search should provide enough details to implement it. If this question isn't answered soon, I'll post a quick example.
的观察者设计模式中没有定义的STL
。您可以参考“四人组”设计模式一书,或者谷歌搜索应该提供足够的细节来实现它。如果这个问题没有很快得到回答,我会发布一个简单的例子。
回答by THRINATH
#include<iostream>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
class Customer;
class flipkart
{
vector<Customer*>list;
vector<Customer*>::iterator it;
public:
void Register(Customer *customer)
{
list.push_back(customer);
}
void unregister(Customer *customer)
{
list.erase(remove(list.begin(), list.end(),customer), list.end());
}
void notify(string item,float vprice);
};
class observer
{
public:
virtual void update(string item,float vprice)=0;
};
class Customer:public observer
{
string name;
public:
Customer(string n)
{
name=n;
}
void update(string item,float vprice)
{
cout<<"**Flipkart**updated price for "<<item<<" is:"<<vprice<<" Rupees only, request recieved by "<<name<<endl;
}
};
void flipkart::notify(string item,float vprice)
{
for(it=list.begin();it!=list.end();it++)
{
(*it)->update(item,vprice);
}
}
class product:public flipkart
{
public:
void change_price(string item,float vprice)
{
notify(item,vprice);
}
};
int main()
{
Customer customer1("Dhoni"),customer2("Yuvraj"),customer3("Kohli");
product LCD;
LCD.Register(&customer1);
LCD.Register(&customer2);
LCD.Register(&customer3);
LCD.change_price("LCD HD2 TV",12000);
LCD.unregister(&customer2);
cout<<"after unregisterng customer2:\n";
LCD.change_price("LCD HD2 TV",11500);
}