Observer sample code
#include <stdio.h>
// Singly-linked list from Ken Russell. Based on libg++ but as a template.
#include "SLList.h"
class Subject;
class Observer {
public:
virtual ~Observer() {}
virtual void Update(Subject *s) = 0;
};
class Subject {
public:
virtual ~Subject() {}
void Attach(Observer *o);
void Detach(Observer *o);
void Notify();
private:
SLList<Observer*> observers;
};
void Subject::Attach(Observer *o) {
observers.append(o);
}
void Subject::Detach(Observer *o) {
observers.del(o);
}
void Subject::Notify() {
for(Pix p = observers.first(); p; observers.next(p)) {
observers(p)->Update(this);
}
}
/*****************************************************************************/
class MySubject : public Subject {
public:
MySubject() { x = 0; }
int GetX() { return x; }
void SetX(int new_x) { x = new_x; Notify(); }
private:
int x;
};
// Observer for MySubject
class MyObserver : public Observer {
public:
virtual ~MyObserver() { subject->Detach(this); }
virtual void Watch(MySubject &s) {
s.Attach(this); subject = &s; Update(&s);
}
virtual void Update(Subject *s) {}
protected:
MySubject *subject;
};
/*****************************************************************************/
// Two specific Observers:
// one that echoes subject->x in decimal
// and one that echoes in hex.
class DecimalObserver : public MyObserver {
public:
virtual void Update(Subject *s);
};
void DecimalObserver::Update(Subject *s)
{
// This equality allows us to use a MySubject object instead
// of a Subject object.
if(subject == s) {
printf("decimal: %d\n", subject->GetX());
}
}
class HexObserver : public MyObserver {
public:
virtual void Update(Subject *s);
};
void HexObserver::Update(Subject *s)
{
// This equality allows us to use a MySubject object instead
// of a Subject object.
if(subject == s) {
printf("hex: %x\n", subject->GetX());
}
}
/*****************************************************************************/
main()
{
MySubject subject;
DecimalObserver decimal;
decimal.Watch(subject);
HexObserver hex;
hex.Watch(subject);
int i;
// X is echoed in decimal and hex each time
for(i = 0; i < 100; i += 10) {
subject.SetX(i);
}
subject.Detach(&decimal);
// Now only in hex
for(; i < 200; i += 10) {
subject.SetX(i);
}
}
Thomas Minka
Last modified: Tue Jan 7 14:10:53 EST 1997