C++ observer pattern implementation

[ permalink ] [ download ]
#include <iostream>
#include <iterator>
#include <deque>
// Implementation of the observer pattern
// its implemented in the java way :D

template <typename T>
class Observer
{
public:
  Observer(){}
  virtual ~Observer () {}
  virtual void update (T * arg){}
};

template <typename T>
class Observable
{
private:
  T * self;
  typedef std::deque<Observer<T> *> ObserverContainer;
  ObserverContainer observers;
public:
  Observable (T * self_){self=self_;}
  virtual ~Observable(){}
  void addObserver(Observer<T> * ob)
  {observers.push_back(ob);}
  void deleteObserver (Observer<T> * ob)
  {
    // Before you use this method you shoule be 
    // sure you are not doing nasty things..., since
    // it can carry HUGE memory problems, in this
    // case we are deleting observers using its
    // pointer for looking for it. Think about the
    // problems this can carry on!!!! (stored Objects, 
    // objects stored on different thread stacks...) 
    // To solve this, assign an OID to each observer, 
    // using a Creator class, and store in a map in the observable!!.
    observers.erase(std::remove_if(observers.begin()
                                  ,observers.end()
                                  ,std::bind2nd(std::equal_to<Observer <T> *>(),ob)));
  }
  void cleanObservers()
  {
    observers.clean();
  }
  void notifyObservers()
  {
    // Since this declaration is template argument dependant
    // its necessary to add the typename keyword.
    typename ObserverContainer::iterator it;
    for (it = observers.begin()
         ;it!=observers.end()
         ;(*it++)->update(self));
  }
};

class View : public Observable<View>
{
private:
  std::string name;
public:
  View(std::string name_):Observable<View>(this), name(name_){}
  ~View(){}
  std::string getName() {return this->name;}
  
};

class ViewController : public Observer<View> 
{
public:
  ViewController(){}
  ~ViewController(){}
  void update (View * arg)
  {
    std::cout<<arg->getName()<<" Has changed!!"<<std::endl;
  }
};

int main (int argc, char * argv)
{
  ViewController vc;
  View v1 ("View 1");
  View v2 ("View 2");
  v1.addObserver(&vc);
  v2.addObserver(&vc);
  v1.notifyObservers();
  v2.notifyObservers();
  return 0;
}
hits counter