// file: uml3.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 // // .---------------. // . Institute . // .---------------. // . . // . . // . . // .---------------. // . addBuilding() . // .---------------. // ^ // v (aggregation) // | // | // |* // .---------------. .---------------. // . Building .<*>----------. Room . // .---------------. * .---------------. // . . . number . // . . . length . // . . . width . // .---------------. .---------------. // . addRoom() . . . // .---------------. .---------------. // /-\ // | // | // | // ---------------------------------------- // | | // | | // | | // .---------------. .---------------. // . Classroom . . Office . // .---------------. .---------------. // . occupant . // .---------------. // // where <*> is supposed to be a filled-in diamond (composition> // and /-\ is supposed to be an open triangle (inheritance) // // 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 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 Building has a set of rooms. // Each is on a particular floor. /////////////////////////////////////////////////////////////////////////////// class Building { private: list rooms; // the rooms in the building public: // 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); } // show the contents of the building void show(ostream &out) { 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 { private: list buildings; // pointers to the buildings in this institute public: // Create this institute. Institute() { } // 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; for( p = buildings.begin(); p != buildings.end(); ++p ) { (*p)->show(out); } } }; main() { Institute whatsamattaU; Building b; b.addClassroom(101, 1, 10, 20); b.addClassroom(102, 1, 15, 30); b.addClassroom(201, 2, 20, 25); b.addClassroom(301, 3, 30, 50); b.addOffice(202, 2, 10, 20, "alice"); b.addOffice(204, 2, 10, 20, "dilbert"); whatsamattaU.addBuilding(b); whatsamattaU.show(cout); } /* output: 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 */