7
votes

Motif de conception observateur en C ++

est le modèle de conception observateur déjà défini dans STL (comme le java.util.observer et java.util.observatible en Java)?


2 commentaires

Vraisemblablement à titre d'exemple de la bibliothèque standard d'une autre langue qui a le motif d'observateur intégré à celui-ci.


Boost est-il acceptable pour vous? Sinon, je serais prêt à poster une mise en œuvre standard de non-boost.


7 Réponses :


7
votes

Non, ça ne le fait pas. Le C ++ STL est beaucoup plus petit que la bibliothèque standard de Java. Si vous recherchez quelque chose à développer sur la STL qui est soutenu par presque tout, il conviendrait de jeter un coup d'œil aux bibliothèques de boost. Dans ce cas, vous voudrez peut-être consulter boost.signals qui fournit un signal / Modèle à sous.


0 commentaires

21
votes

non, mais boost.signals2 vous donne quelque chose de similaire.


2 commentaires

+1, boost.signals est génial. Vérifiez également les signaux2 si vous avez plusieurs threads.


Boost.Signals est obsolète, Boost.Signals2 devrait être utilisé à la place.



6
votes

Voici une implémentation de référence (de 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;
}




8
votes

Autant que mes connaissances se rendent en C ++, STL n'a pas de mise en œuvre pour le modèle d'observateur. Il y avait une proposition de signal / emplacement pour la bibliothèque standard dans TR2.

Il existe de nombreuses bibliothèques qui fournissent une mise en œuvre de la bibliothèque QT de modèle d'observateur étant l'un des pionniers. La bibliothèque Boost a une implémentation (voir Boost :: Signals & Boost :: signaux2).

La bibliothèque POCO C ++ a une mise en œuvre soignée du modèle d'observateur (voir NotificationCenter).

LIBSIGC ++, CPP-Événements sont certaines des autres bibliothèques fournissant des implémentations de signal / machine à sous.


0 commentaires

4
votes
#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 commentaires

Le lien est cassé.



0
votes
             #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 commentaires

Le code ci-dessus que j'ai écrit uniquement pour les personnes qui souhaitent connaître l'utilisation de base du modèle de conception d'observateur, veuillez commenter si une erreur merci .... @ Thrinath @.


Bienvenue à Stackoverflow! Pourriez-vous s'il vous plaît élaborer un petit E.G. Comment cela répond à la question?