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