观察者设计模式是否已经在 STL 中定义(如 Java 中的 java.util.Observer 和 java.util.Observable)?
问问题
26704 次
7 回答
21
不,但是Boost.Signals2给你类似的东西。
于 2010-02-08T21:55:44.713 回答
8
据我所知,STL 没有观察者模式的实现。不过,TR2 中有一个标准库的 Signal/Slot 提案。
有很多库为观察者模式 Qt 库提供了实现,Qt 库是其中的先驱之一。boost 库有一个实现(参见 Boost::Signals 和 Boost::Signals2)。
Poco C++ 库有一个简洁的观察者模式实现(参见 NotificationCenter)。
libsigc++、cpp-events 是其他一些提供信号/插槽实现的库。
于 2010-07-27T17:12:00.877 回答
7
不,它没有。C++ STL 比 Java 的标准库小得多。如果您正在寻找一些东西来扩展几乎所有东西都支持的 STL,那么看看 Boost 库是值得的。在这种情况下,您可能需要查看提供信号/插槽模型的Boost.Signals 。
于 2010-02-08T21:55:35.337 回答
6
这是一个参考实现(来自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;
}
于 2010-02-08T21:56:40.920 回答
4
#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;
}
另请参阅 UML/流程图http://codepatterns.ddns.net/
于 2014-09-24T18:51:49.673 回答
2
观察者设计模式未在STL
. 您可以参考“Gang of Four”设计模式一书,或者谷歌搜索应该提供足够的细节来实现它。如果这个问题没有很快得到回答,我会发布一个简单的例子。
于 2010-02-08T21:59:07.223 回答
0
#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);
}
于 2019-05-17T10:36:00.393 回答