//: C10:PaperScissorsRock.cpp // Demonstration of multiple dispatching. #include <algorithm> #include <iostream> #include <iterator> #include <vector> #include <ctime> #include <cstdlib> #include "../purge.h" using namespace std; class Paper; class Scissors; class Rock; enum Outcome { WIN, LOSE, DRAW }; ostream& operator<<(ostream& os, const Outcome out) { switch(out) { default: case WIN: return os << "win"; case LOSE: return os << "lose"; case DRAW: return os << "draw"; } } class Item { public: virtual Outcome compete(const Item*) = 0; virtual Outcome eval(const Paper*) const = 0; virtual Outcome eval(const Scissors*) const= 0; virtual Outcome eval(const Rock*) const = 0; virtual ostream& print(ostream& os) const = 0; virtual ~Item() {} friend ostream& operator<<(ostream& os, const Item* it) { return it->print(os); } }; class Paper : public Item { public: Outcome compete(const Item* it) { return it->eval(this);} Outcome eval(const Paper*) const { return DRAW; } Outcome eval(const Scissors*) const { return WIN; } Outcome eval(const Rock*) const { return LOSE; } ostream& print(ostream& os) const { return os << "Paper "; } }; class Scissors : public Item { public: Outcome compete(const Item* it) { return it->eval(this);} Outcome eval(const Paper*) const { return LOSE; } Outcome eval(const Scissors*) const { return DRAW; } Outcome eval(const Rock*) const { return WIN; } ostream& print(ostream& os) const { return os << "Scissors"; } }; class Rock : public Item { public: Outcome compete(const Item* it) { return it->eval(this);} Outcome eval(const Paper*) const { return WIN; } Outcome eval(const Scissors*) const { return LOSE; } Outcome eval(const Rock*) const { return DRAW; } ostream& print(ostream& os) const { return os << "Rock "; } }; struct ItemGen { Item* operator()() { switch(rand() % 3) { default: case 0: return new Scissors; case 1: return new Paper; case 2: return new Rock; } } }; struct Compete { Outcome operator()(Item* a, Item* b) { cout << a << "\t" << b << "\t"; return a->compete(b); } }; int main() { srand(time(0)); // Seed the random number generator const int sz = 20; vector<Item*> v(sz*2); generate(v.begin(), v.end(), ItemGen()); transform(v.begin(), v.begin() + sz, v.begin() + sz, ostream_iterator<Outcome>(cout, "\n"), Compete()); purge(v); } ///:~
Listado 9.34. C10/PaperScissorsRock.cpp
//: C10:BeeAndFlowers.cpp // Demonstration of "visitor" pattern. #include <algorithm> #include <iostream> #include <string> #include <vector> #include <ctime> #include <cstdlib> #include "../purge.h" using namespace std; class Gladiolus; class Renuculus; class Chrysanthemum; class Visitor { public: virtual void visit(Gladiolus* f) = 0; virtual void visit(Renuculus* f) = 0; virtual void visit(Chrysanthemum* f) = 0; virtual ~Visitor() {} }; class Flower { public: virtual void accept(Visitor&) = 0; virtual ~Flower() {} }; class Gladiolus : public Flower { public: virtual void accept(Visitor& v) { v.visit(this); } }; class Renuculus : public Flower { public: virtual void accept(Visitor& v) { v.visit(this); } }; class Chrysanthemum : public Flower { public: virtual void accept(Visitor& v) { v.visit(this); } }; // Add the ability to produce a string: class StringVal : public Visitor { string s; public: operator const string&() { return s; } virtual void visit(Gladiolus*) { s = "Gladiolus"; } virtual void visit(Renuculus*) { s = "Renuculus"; } virtual void visit(Chrysanthemum*) { s = "Chrysanthemum"; } }; // Add the ability to do "Bee" activities: class Bee : public Visitor { public: virtual void visit(Gladiolus*) { cout << "Bee and Gladiolus" << endl; } virtual void visit(Renuculus*) { cout << "Bee and Renuculus" << endl; } virtual void visit(Chrysanthemum*) { cout << "Bee and Chrysanthemum" << endl; } }; struct FlowerGen { Flower* operator()() { switch(rand() % 3) { default: case 0: return new Gladiolus; case 1: return new Renuculus; case 2: return new Chrysanthemum; } } }; int main() { srand(time(0)); // Seed the random number generator vector<Flower*> v(10); generate(v.begin(), v.end(), FlowerGen()); vector<Flower*>::iterator it; // It's almost as if I added a virtual function // to produce a Flower string representation: StringVal sval; for(it = v.begin(); it != v.end(); it++) { (*it)->accept(sval); cout << string(sval) << endl; } // Perform "Bee" operation on all Flowers: Bee bee; for(it = v.begin(); it != v.end(); it++) (*it)->accept(bee); purge(v); } ///:~
Listado 9.35. C10/BeeAndFlowers.cpp