⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 observedflower.cpp

📁 Think in C++ 第二版源码
💻 CPP
字号:
//: C25:ObservedFlower.cpp

// From Thinking in C++, 2nd Edition

// Available at http://www.BruceEckel.com

// (c) Bruce Eckel 1999

// Copyright notice in Copyright.txt

// Demonstration of "observer" pattern

#include "Observable.h"

#include <iostream>

#include <vector>

#include <algorithm>

#include <string>

using namespace std;



class Flower {

  bool isOpen;

public:

  Flower() : isOpen(false), 

    openNotifier(this), closeNotifier(this) {}

  void open() { // Opens its petals

    isOpen = true;

    openNotifier.notifyObservers();

    closeNotifier.open();

  }

  void close() { // Closes its petals

    isOpen = false;

    closeNotifier.notifyObservers();

    openNotifier.close();

  }

  // Using the "inner class" idiom:

  class OpenNotifier;

  friend class Flower::OpenNotifier;

  class OpenNotifier : public Observable {

    Flower* parent;

    bool alreadyOpen;

  public:

    OpenNotifier(Flower* f) : parent(f), 

      alreadyOpen(false) {}

    void notifyObservers(Argument* arg=0) {

      if(parent->isOpen && !alreadyOpen) {

        setChanged();

        Observable::notifyObservers();

        alreadyOpen = true;

      }

    }

    void close() { alreadyOpen = false; }

  } openNotifier;

  class CloseNotifier;

  friend class Flower::CloseNotifier;

  class CloseNotifier : public Observable {

    Flower* parent;

    bool alreadyClosed;

  public:

    CloseNotifier(Flower* f) : parent(f), 

      alreadyClosed(false) {}

    void notifyObservers(Argument* arg=0) {

      if(!parent->isOpen && !alreadyClosed) {

        setChanged();

        Observable::notifyObservers();

        alreadyClosed = true;

      }

    }

    void open() { alreadyClosed = false; }

  } closeNotifier;

};



class Bee {

  string name;

  // An "inner class" for observing openings:

  class OpenObserver;

  friend class Bee::OpenObserver;

  class OpenObserver : public Observer {

    Bee* parent;

  public:

    OpenObserver(Bee* b) : parent(b) {}

    void update(Observable*, Argument *) {

      cout << "Bee " << parent->name 

        << "'s breakfast time!\n";

    }

  } openObsrv;

  // Another "inner class" for closings:

  class CloseObserver;

  friend class Bee::CloseObserver;

  class CloseObserver : public Observer {

    Bee* parent;

  public:

    CloseObserver(Bee* b) : parent(b) {}

    void update(Observable*, Argument *) {

      cout << "Bee " << parent->name 

        << "'s bed time!\n";

    }

  } closeObsrv;

public:

  Bee(string nm) : name(nm), 

    openObsrv(this), closeObsrv(this) {}

  Observer& openObserver() { return openObsrv; }

  Observer& closeObserver() { return closeObsrv;}

};



class Hummingbird {

  string name;

  class OpenObserver;

  friend class Hummingbird::OpenObserver;

  class OpenObserver : public Observer {

    Hummingbird* parent;

  public:

    OpenObserver(Hummingbird* h) : parent(h) {}

    void update(Observable*, Argument *) {

      cout << "Hummingbird " << parent->name 

        << "'s breakfast time!\n";

    }

  } openObsrv;

  class CloseObserver;

  friend class Hummingbird::CloseObserver;

  class CloseObserver : public Observer {

    Hummingbird* parent;

  public:

    CloseObserver(Hummingbird* h) : parent(h) {}

    void update(Observable*, Argument *) {

      cout << "Hummingbird " << parent->name 

        << "'s bed time!\n";

    }

  } closeObsrv;

public:

  Hummingbird(string nm) : name(nm), 

    openObsrv(this), closeObsrv(this) {}

  Observer& openObserver() { return openObsrv; }

  Observer& closeObserver() { return closeObsrv;}

};



int main() {

  Flower f;

  Bee ba("A"), bb("B");

  Hummingbird ha("A"), hb("B");

  f.openNotifier.addObserver(ha.openObserver());

  f.openNotifier.addObserver(hb.openObserver());

  f.openNotifier.addObserver(ba.openObserver());

  f.openNotifier.addObserver(bb.openObserver());

  f.closeNotifier.addObserver(ha.closeObserver());

  f.closeNotifier.addObserver(hb.closeObserver());

  f.closeNotifier.addObserver(ba.closeObserver());

  f.closeNotifier.addObserver(bb.closeObserver());

  // Hummingbird B decides to sleep in:

  f.openNotifier.deleteObserver(hb.openObserver());

  // Something changes that interests observers:

  f.open();

  f.open(); // It's already open, no change.

  // Bee A doesn't want to go to bed:

  f.closeNotifier.deleteObserver(

    ba.closeObserver());

  f.close();

  f.close(); // It's already closed; no change

  f.openNotifier.deleteObservers();

  f.open();

  f.close();

} ///:~

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -