// file: uml4.cc // author: keller // RCS: $Id: uml3.cc,v 1.1 2000/02/07 20:51:36 keller Exp $ // // purpose: modeling the following UML class diagram // // .---------------. // . NamedObject . // .---------------. // . name . // . . // . . // .---------------. // /_\ // | .---------------. // | . Institute . // | .---------------. // | . . // | . . // |----. . // | .---------------. // | . addBuilding() . // | .---------------. // | ^ // | v (aggregation) // | | // | | // | |* // | .---------------. .---------------. // | . Building .<*>----------. Room . // | .---------------. * .---------------. // | . . . number . // |----. . . length . // . . . width . // .---------------. .---------------. // . addRoom() . . . // .---------------. .---------------. // /-\ // | // | // | // ---------------------------------------- // | | | // | | | // | | | // .---------------. .---------------. .---------------. // . Classroom . . Suite . . Office . // .---------------. .---------------. .---------------. // . occupant . // .---------------. // // where <*> is supposed to be a filled-in diamond (composition> // /-\ is supposed to be an open triangle (inheritance) // and <> is supposed to be an open diamond (aggregation) // // Note: For purposes of exposition and conciseness, we do not use separate // header files, etc., nor do we include all constructors, destructors, // and assignment operators. #include // the STL list template #include // the STL string class class Building; // forward declaration /////////////////////////////////////////////////////////////////////////////// // A NamedObject is an Object that has a name. /////////////////////////////////////////////////////////////////////////////// class NamedObject { protected: string name; public: // Create a NamedObject NamedObject(string name) { this->name = name; } string getName() { return name; } }; /////////////////////////////////////////////////////////////////////////////// // A Room is in a Building. // It has a number, length, and width. // It knows its building. // This class is abstract; we only directly create specific types of rooms. /////////////////////////////////////////////////////////////////////////////// class Room { protected: Building *building; // the building containing this room int number; // the room number of this room int length; // the length of the room in feet int width; // the width of the room in feet public: // create a room in a building Room(Building *building, int number, int length, int width) { this->building = building; this->number = number; this->length = length; this->width = width; } // print a description of the room, including the type of room // If this were not declared 'virtual', then calling the method of this name // would always use the one in the base class, rather than in the derived // class which might over-ride it. virtual void show(ostream &out) { out << "room " << number << " " << length << "x" << width << " " << type() << endl; } virtual string type() = 0; // pure virtual method // (causes class to be abstract) // Without a virtual type method, we would // have no right to refer to specialize // the type to the derived classes. virtual ~Room() // virtual destructor { } }; /////////////////////////////////////////////////////////////////////////////// // A Classroom is a kind of Room. /////////////////////////////////////////////////////////////////////////////// class Classroom : public Room { public: // create a classroom in a building Classroom(Building *building, int number, int length, int width) : Room(building, number, length, width) { } string type() { return "classroom"; } }; /////////////////////////////////////////////////////////////////////////////// // An Office is a kind of Room. // It has an occupant. /////////////////////////////////////////////////////////////////////////////// class Office : public Room { private: string occupant; public: // Create an office in a building for a specific occupant. Office(Building *building, int number, int length, int width, string occupant) : Room(building, number, length, width) { this->occupant = occupant; } string type() { return "office"; } // print a description of the room, including the type of room and occupant // (over-rides show in the base class) void show(ostream &out) { out << "room " << number << " " << length << "x" << width << " " << type() << " " << occupant << endl; } }; /////////////////////////////////////////////////////////////////////////////// // A Suite is a kind of Room. /////////////////////////////////////////////////////////////////////////////// class Suite : public Room { public: // Create an office in a building for a specific occupant. Suite(Building *building, int number, int length, int width) : Room(building, number, length, width) { } string type() { return "Suite"; } // print a description of the room, including the type of room and occupant // (over-rides show in the base class) void show(ostream &out) { out << "suite " << number << " " << length << "x" << width << " " << type() << " " << endl; } }; /////////////////////////////////////////////////////////////////////////////// // A Building has a set of rooms. // Each is on a particular floor. /////////////////////////////////////////////////////////////////////////////// class Building : public NamedObject { private: list rooms; // the rooms in the building public: // Create a Building. Building(string name) : NamedObject(name) { } // create a classroom in the building void addClassroom(int number, int floor, int length, int width) { Room *theNewRoom = new Classroom(this, number, length, width); rooms.push_back(theNewRoom); } // create an office in the building void addOffice(int number, int floor, int length, int width, string occupant) { Room *theNewRoom = new Office(this, number, length, width, occupant); rooms.push_back(theNewRoom); } // create a suite in the building void addSuite(int number, int floor, int length, int width) { Room *theNewRoom = new Suite(this, number, length, width); rooms.push_back(theNewRoom); } // show the contents of the building void show(ostream &out) { out << "Building: " << getName() << endl; list::iterator p; for( p = rooms.begin(); p != rooms.end(); ++p ) { (*p)->show(out); } } }; /////////////////////////////////////////////////////////////////////////////// // An Institute has a set of Buildings. // The buildings exist independent of the institute. /////////////////////////////////////////////////////////////////////////////// class Institute : public NamedObject { private: list buildings; // pointers to the buildings in this institute public: // Create an Institute. Institute(string name) : NamedObject(name) { } // Add a building to this institute. addBuilding(Building &building) { buildings.push_back(&building); // add pointer to building } // Print a description of this Institute. virtual void show(ostream &out) { list::iterator p; out << "Institute: " << getName() << endl; for( p = buildings.begin(); p != buildings.end(); ++p ) { (*p)->show(out); } } }; main() { Institute whatsamattaU("WhatsaMattU"); Building a("WMU Administration"); Building d("WMU Dorm"); a.addClassroom(101, 1, 10, 20); a.addClassroom(102, 1, 15, 30); a.addClassroom(201, 2, 20, 25); a.addClassroom(301, 3, 30, 50); a.addOffice(202, 2, 10, 20, "alice"); a.addOffice(204, 2, 10, 20, "dilbert"); d.addSuite(110, 1, 15, 20); d.addSuite(120, 1, 15, 20); d.addSuite(130, 1, 15, 20); d.addSuite(210, 1, 15, 20); d.addSuite(220, 1, 15, 20); d.addSuite(230, 1, 15, 20); whatsamattaU.addBuilding(a); whatsamattaU.addBuilding(d); whatsamattaU.show(cout); } /* output: Institute: WhatsaMattU Building: WMU Administration room 101 10x20 classroom room 102 15x30 classroom room 201 20x25 classroom room 301 30x50 classroom room 202 10x20 office alice room 204 10x20 office dilbert Building: WMU Dorm suite 110 15x20 Suite suite 120 15x20 Suite suite 130 15x20 Suite suite 210 15x20 Suite suite 220 15x20 Suite suite 230 15x20 Suite */