// file: composite.cpp // author: Robert Keller // purpose: Illustrating composite class definition in C++ // note: In-line method definitions are used intentionally for conciseness. // description: // An Item can be either // an Atom, having no apparent sub-strcture, or // a Container, containing a list of (pointers to) Items // In effect, Item is an abstract class used only to unite the two // concepts of Atom and Container as a single concept. // All Items have names. There is a method for adding Items to a // container, and one for showing any Item on an ostream. // Atoms are shown as their name, while Containers are shown as the // name, followed by the showing of a list of the contained Items // in brackets and separated by commas. #include #include #include // the base class class Item { protected: string name; public: // Construct an Item with a given name. // Since Item contains a pure virtual method, the constructor cannot be // called directly, but only in the context of the constructor of one // of the derived classes. Item(string _name) : name(_name) { } // Show the Item. virtual void show(ostream& out) = 0; // pure virtual method }; // class Item // An Atom is an Item that cannot contain others. class Atom : public Item { public: // construct an Atom Atom(string name) : Item(name) { } // Show the Atom. void show(ostream& out) { out << name; } }; // class Atom // A Container is an Item that contains a list of (pointers to) others. class Container : public Item { private: list items; public: // Construct a Container with a given name. Container(string name) : Item(name) { } // Add an Item to a Container. void add(Item& item) { items.push_back(&item); } // Show the Container. void show(ostream& out) { out << name << "["; // Show container name and [. list::iterator i = items.begin(); if( i != items.end() ) { (*i)->show(out); // Show first Item specially. } i++; for( ; i != items.end(); i++ ) // Show other Items preceded by commas. { out << ", "; (*i)->show(out); } out << "]"; // Show matching ]. } }; // class Container // test program main() { Container cart("cart"); Atom apple("apple"); Atom banana("banana"); cart.add(apple); cart.add(banana); cart.add(apple); cart.show(cout); cout << endl; Container wagon("wagon"); Atom watermelon("watermelon"); Atom pumpkin("pumpkin"); wagon.add(watermelon); wagon.add(pumpkin); Container train("train"); train.add(cart); train.add(wagon); train.show(cout); cout << endl; } /* sample output cart[apple, banana, apple] train[cart[apple, banana, apple], wagon[watermelon, pumpkin]] */