7

Is the observer design pattern already defined in STL (Like the java.util.Observer and java.util.Observable in Java) ?

2
  • 2
    Presumably as an example of another language's standard library that has the observer pattern built into it. Commented Feb 8, 2010 at 22:07
  • Is boost acceptable to you? If not I would be willing to post a standard non-boost implementation.
    – Dan O
    Commented Feb 9, 2010 at 1:34

7 Answers 7

21

No, but Boost.Signals2 gives you something similar.

2
  • 2
    +1, Boost.Signals is great. Also check Signals2 if you have multiple threads.
    – Manuel
    Commented Feb 8, 2010 at 22:06
  • 2
    Boost.Signals is deprecated, Boost.Signals2 should be used instead.
    – shi
    Commented Aug 11, 2016 at 15:23
8

As far as my knowledge goes in C++, STL doesn't have an implementation for Observer pattern. There was a proposal for Signal/Slot for standard library in TR2 though.

There are plenty of libraries which provides implementation for Observer pattern Qt library being one of the pioneers. The boost library has an implementation (see Boost::Signals & Boost::Signals2).

The Poco C++ library has a neat implementation of the observer pattern (see NotificationCenter).

libsigc++, cpp-events are some of the other libraries that provide signal/slot implementations.

7

No it doesn't. The C++ STL is much smaller than Java's Standard Library. If you are looking for something to expand on the STL that is supported by almost everything, it would be worth taking a look at the Boost libraries. In this case you may want to look at Boost.Signals which provides a signal/slot model.

6

Here is a reference implementation (from 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;
}
5
  • 14
    Hard to take seriously a C++ implementation that uses illegal member function names such as _Notify.
    – anon
    Commented Feb 8, 2010 at 22:00
  • 1
    Apparently it has other problems as well. Check the discussion page: en.wikipedia.org/wiki/…
    – Manuel
    Commented Feb 8, 2010 at 22:09
  • 2
    hmmm... maybe my answer should have been "Modify the code located here to a reference implementation" :(
    – Hogan
    Commented Feb 8, 2010 at 22:30
  • 6
    C++ implementation has been removed from the wikipedia article.
    – pmb
    Commented Jul 5, 2013 at 11:13
  • 1
    @NickBedford is it valid C++ because it compiles? The standard is quite clear actually: from §2.10.3.1 "Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use." I think the example should be changed, besides I see no real useful reason for the function to be prefixed with an underscore. Add §17.6.4.3.2 "If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined." Commented Aug 15, 2016 at 8:17
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;
}

please also see UML/flow diagrams http://codepatterns.ddns.net/

1
  • The link is broken.
    – Enlico
    Commented Mar 22, 2020 at 7:59
2

The Observer design pattern is not defined in the STL. You can refer to the "Gang of four" Design Patterns book or a Google search should provide enough details to implement it. If this question isn't answered soon, I'll post a quick example.

2
  • Or you can copy-paste the Wikipedia implementation that somebody has linked in another answer
    – Manuel
    Commented Feb 8, 2010 at 22:02
  • thanks! Boost signals look interesting. I have used Boost for random number generation but never for an observer pattern or signals as they call it. Anyhow, I think evaluating the GOF observer pattern and Boost Signals is a good idea at least for academic purposes. Commented Feb 8, 2010 at 22:07
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);
             }
2
  • The above code I wrote only for people who want to know the basic usage of observer design pattern,please comment if any mistake thank you....@THRINATH@.
    – THRINATH
    Commented May 17, 2019 at 10:44
  • Welcome to StackOverflow! Could you please elaborate a little e.g. how this answers the question?
    – obscure
    Commented May 17, 2019 at 10:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.