/////////////////////////////////////////////////////////// // Softwarebauelemente II, Aufgabe O3.1 // // author: Stephan Brumme // last changes: May 15, 2001 #include "House.h" // needed for std::find #include CHouse::CHouse() { m_Set.empty(); m_itCursor = m_Set.begin(); } CHouse::CHouse(const CHouse& house) { operator=(house); } // constructs a new house using its date of foundation (default: today) CHouse::CHouse(const CDate& dtDateOfFoundation) { m_dtDateOfFoundation = dtDateOfFoundation; m_Set.empty(); m_itCursor = m_Set.begin(); } // show attributes string CHouse::Show() const { ostringstream strOutput; // some general information strOutput << "The house was founded on " << m_dtDateOfFoundation.Show() << " and consists of " << m_Set.size() << " rooms: " << endl; // stream all rooms TSetConstCursor itCursor; for (itCursor = m_Set.begin(); itCursor != m_Set.end(); itCursor++) strOutput << " " << itCursor->Show() << endl; return strOutput.str(); } // shows all internal attributes string CHouse::ShowDebug() const { ostringstream strOutput; // print any information about this class strOutput << "DEBUG info for 'CHouse'" << endl << " m_dtDateOfFoundation=" << m_dtDateOfFoundation.Show() << endl << " m_nCount=" << m_Set.size() << endl; // stream all rooms // this iterator needs to be const ... TSetConstCursor itCursor; strOutput << " m_vecSet=" << endl; for (itCursor = m_Set.begin(); itCursor != m_Set.end(); itCursor++) strOutput << " " << itCursor->Show() << endl; return strOutput.str(); } // validate a house bool CHouse::ClassInvariant() const { // check date of foundation if (!m_dtDateOfFoundation.ClassInvariant()) return false; // empty set if (m_Set.empty()) return true; // no room should be held twice in the array TSetConstCursor itCursor; itCursor = m_Set.begin(); while (itCursor != m_Set.end()) { // next room itCursor++; // look for exact copy TSetConstCursor itFind; itFind = std::find(itCursor, m_Set.end(), *itCursor); // copy found ? if (itFind != m_Set.end()) return false; } return true; } // copy constructor CHouse& CHouse::operator =(const CHouse &house) { m_dtDateOfFoundation = house.m_dtDateOfFoundation; m_itCursor = house.m_itCursor; // container performs the whole copy internally m_Set = house.m_Set; return *this; } // virtual, see operator= bool CHouse::Copy(const CBasicClass* pClass) { // cast to CHouse CBasicClass *basic; CHouse *house; basic = const_cast(pClass); house = dynamic_cast(basic); // invalid class (is NULL when pClass is not a CHouse) if (house == NULL || house == this) return false; // use non virtual reference based copy // return value isn't needed operator=(*house); // we're done return true; } // compare two houses bool CHouse::operator ==(const CHouse &house) const { // compare date of foundation if (!(m_dtDateOfFoundation == house.m_dtDateOfFoundation)) return false; // find each room of the given house in our house TSetConstCursor itCursor; for (itCursor = house.m_Set.begin(); itCursor != house.m_Set.end(); itCursor++) // I re-implement the find method because of keeping this method const if (std::find(m_Set.begin(), m_Set.end(), *itCursor) == m_Set.end()) return false; // all rooms were found return true; } // virtual, see operator== bool CHouse::EqualValue(const CBasicClass* pClass) const { // cast to CHouse CBasicClass *basic; CHouse *house; basic = const_cast(pClass); house = dynamic_cast(basic); // invalid class (is NULL when pClass is not a CHouse) if (house == NULL || house == this) return false; // use non virtual reference based copy return operator==(*house); } // return date of foundation CDate CHouse::GetDateOfFoundation() const { return m_dtDateOfFoundation; } // return number of stored rooms int CHouse::Card() const { return m_Set.size(); } // insert a new room into the set, TRUE if successful // will fail if room already exists bool CHouse::Insert(const CRoom &room) { // there must be some memory to grow the set // and the room must not be part of the list if (m_Set.size() < m_Set.max_size() && !Find(room)) { // insert at the tail of the list m_Set.push_back(room); return true; } else return false; } // return first stored room, TRUE if successful bool CHouse::GetFirst(CRoom &room) { // set must not be empty if (m_Set.empty()) return false; // set cursor to first room m_itCursor = m_Set.begin(); // get this room room = *m_itCursor; return true; } // return next room, TRUE if successful bool CHouse::GetNext(CRoom &room) { // set must not be empty, end must not be reached if (m_Set.empty() && m_itCursor != m_Set.end()) return false; // iterate to next object m_itCursor++; // get this object room = *m_itCursor; return true; } // look for a room and set cursor, TRUE if successful bool CHouse::Find(const CRoom &room) { // set must not be empty if (m_Set.empty()) return false; // create new iterator TSetCursor itCursor; // use STL's find itCursor = std::find(m_Set.begin(), m_Set.end(), room); // change m_itCursor if room was found if (itCursor != m_Set.end()) { m_itCursor = itCursor; return true; } else return false; } // return the room the cursor points to, TRUE if successful bool CHouse::GetCurrent(CRoom &room) const { // set must not be empty if (m_Set.empty()) return false; // return current room room = *m_itCursor; return true; } // erase current room, TRUE if successful bool CHouse::Scratch() { // set must not be empty if (m_Set.empty()) return false; // erase room, set cursor to next room m_itCursor = m_Set.erase(m_itCursor); return true; }