有一个subject, 一群observer, subject的实例保存了observer的列表,当发生改变的时候可以通知observer进行update。
#include <iostream> #include <list> #include <algorithm> using namespace std; class Observer { public: virtual void update(float temp, float humidity, float pressure) { } bool operator == (const Observer* o1) { return o1 == this; } }; class DisplayElement { public: virtual void display() { } }; class Subject { public: virtual void registerObserver(Observer* o) = 0; virtual void removeObserver(Observer* o) = 0; virtual void notifyObservers() = 0; }; class WeatherData : public Subject { private: list<Observer*>* observers; float temperature; float humidity; float pressure; public: WeatherData() { observers = new list<Observer*>(); } virtual void registerObserver(Observer* o) { observers->push_back(o); } virtual void removeObserver(Observer* o) { observers->remove(o); } virtual void notifyObservers() { for(list<Observer*>::iterator it = observers->begin() ; it != observers->end(); ++it) { (*it)->update(temperature, humidity, pressure); } } void measurementsChanged() { notifyObservers(); } void setMeasurements(float temperature, float humidity, float pressure) { this->temperature = temperature; this->humidity = humidity; this->pressure = pressure; measurementsChanged(); } }; class CurrentConditionDisplay : public Observer, public DisplayElement { private: float temperature; float humidity; WeatherData weatherData; public: CurrentConditionDisplay(WeatherData weatherData) { this->weatherData = weatherData; weatherData.registerObserver(this); } virtual void update(float temperature, float humidity, float pressure) { this->temperature = temperature; this->humidity = humidity; display(); } virtual void display() { cout<<"current conditions: " << temperature << " F degrees and " << humidity <<"%humidity"<<endl; } }; int main() { WeatherData* weatherData = new WeatherData(); CurrentConditionDisplay* currentDisplay = new CurrentConditionDisplay(*weatherData); CurrentConditionDisplay* currentDisplay2 = new CurrentConditionDisplay(*weatherData); weatherData->setMeasurements(80, 65, 30.4f); weatherData->setMeasurements(82, 70, 29.2f); weatherData->removeObserver(currentDisplay2); weatherData->setMeasurements(78, 90, 29.2f); }
按惯例记录将代码用c++重写遇到的问题。
1. 抽象类不能有实例。 所以如果需要实例,只好避免使用纯虚函数,而改为在函数里不写代码。
2. list的应用时候由于这个是定义类型,且remove需要使用==来判断是否删除,这时候需要在observer对==进行运算符重载。
3. 在本例中直接保存对象到list,在比较的时候会比较麻烦,所以采用保存observer的指针到list,比较时候采用的是比较指针指向的地址是否相同。本对象的指针其实就是this。
4. 之所以把observers设置为指针是因为new list返回的是指针类型。而如果将observers = new list<Observer*>(); 写成observers = list<Observer*>(); 编译能通过但是会出现list iterator not dereferencable。 应该是new与不new上有区别。
5. 由于原java程序中,接口很多,所以在c++实现的过程中不可避免的要用到多重继承,在更复杂的情况在还可能需要用到虚基类。不知道是否有更好的方法来替代java中的接口。