sources:
BasicClass.h (1.4k)
C1_1.cpp (604 bytes)
CashOffice.cpp (3.8k)
CashOffice.h (1.8k)
Date.cpp (6.0k)
Date.h (2.9k)
Exception.cpp (2.5k)
Exception.h (1.4k)
House.cpp (7.5k)
House.h (2.7k)
Room.cpp (3.0k)
Room.h (1.6k)


binaries:
Release/C1_1.exe (140.0k)


website:
more info here
studies/bauelemente/Softwarebauelemente-CodeC1-1/House.cpp
download file

  1 ///////////////////////////////////////////////////////////
  2 // Softwarebauelemente II, Aufgabe C1.1
  3 //
  4 // author: Stephan Brumme
  5 // last changes: July 3, 2001
  6
  7
  8 #include "House.h"
  9 #include "Exception.h"
 10
 11 // needed for std::find
 12 #include <algorithm>
 13
 14
 15
 16 CHouse::CHouse()
 17 {
 18     m_Set.empty();
 19     m_itCursor = m_Set.begin();
 20 }
 21
 22 CHouse::CHouse(const CHouse& house)
 23 {
 24     operator=(house);
 25 }
 26
 27 // constructs a new house using its date of foundation (default: today)
 28 CHouse::CHouse(const CDate& dtDateOfFoundation)
 29 {
 30     m_dtDateOfFoundation = dtDateOfFoundation;
 31     m_Set.empty();
 32     m_itCursor = m_Set.begin();
 33 }
 34
 35
 36 // show attributes
 37 string CHouse::Show() const {
 38     // check invariance
 39     if (!ClassInvariant())
 40         return "";
 41
 42     ostringstream strOutput;
 43
 44     // some general information
 45     strOutput << "The house was founded on " << m_dtDateOfFoundation.Show()
 46               << " and consists of "
 47               << m_Set.size() << " rooms: " << endl;
 48    
 49     // stream all rooms
 50     TSetConstCursor itCursor;
 51
 52     for (itCursor = m_Set.begin(); itCursor != m_Set.end(); itCursor++)
 53         strOutput << " " << itCursor->Show() << endl;
 54
 55     return strOutput.str();
 56 }
 57
 58
 59 // shows all internal attributes
 60 string CHouse::ShowDebug() const {
 61     ostringstream strOutput;
 62
 63     // print any information about this class
 64     strOutput << "DEBUG info for 'CHouse'" << endl
 65          <<  " m_dtDateOfFoundation=" << m_dtDateOfFoundation.Show() << endl          << " m_nCount="   << m_Set.size() << endl;
 66
 67     // stream all rooms
 68     // this iterator needs to be const ...
 69     TSetConstCursor itCursor;
 70
 71     strOutput <<  " m_vecSet="   << endl;
 72     for (itCursor = m_Set.begin(); itCursor != m_Set.end(); itCursor++)
 73         strOutput << " " << itCursor->Show() << endl;
 74
 75     return strOutput.str();
 76 }
 77
 78
 79 // validate a house
 80 bool CHouse::ClassInvariant() const {
 81     // check date of foundation
 82     if (!m_dtDateOfFoundation.ClassInvariant())
 83         return false;
 84
 85     // no room should be held twice in the array
 86     TSetConstCursor itCursor;
 87     itCursor = m_Set.begin();
 88
 89     while (itCursor != m_Set.end())
 90     {
 91         // verify invariance of each stored room
 92         if (!itCursor->ClassInvariant())
 93             return false;
 94
 95         // next room
 96         itCursor++;
 97
 98         // look for exact copy
 99         TSetConstCursor itFind;
100         itFind = std::find(itCursor, m_Set.end(), *itCursor);
101
102         // copy found ?
103 // if (itFind != m_Set.end())
104 // return false;
105     }
106
107     return true;
108 }
109
110
111 // copy constructor
112 CHouse& CHouse::operator =(const CHouse &house)
113 {
114     m_dtDateOfFoundation = house.m_dtDateOfFoundation;
115     m_itCursor = house.m_itCursor;
116     // container performs the whole copy internally
117     m_Set      = house.m_Set;
118
119     return *this;
120 }
121
122
123 // virtual, see operator=
124 bool CHouse::Copy(const CBasicClass* pClass)
125 {
126     // cast to CHouse
127     const CHouse *house = dynamic_cast<const CHouse*>(pClass);
128
129     // invalid class (is NULL when pClass is not a CHouse)
130     if (house == NULL || house == this)
131         return false;
132
133     // use non virtual reference based copy
134     // return value isn't needed
135     operator=(*house);
136
137     // we're done
138     return true;
139 }
140
141
142 // compare two houses
143 bool CHouse::operator ==(const CHouse &house) const {
144     // compare date of foundation
145     if (!(m_dtDateOfFoundation == house.m_dtDateOfFoundation))
146         return false;
147
148     // find each room of the given house in our house
149     TSetConstCursor itCursor;
150     for (itCursor = house.m_Set.begin(); itCursor != house.m_Set.end(); itCursor++)
151         // I re-implement the find method because of keeping this method const
152         if (std::find(m_Set.begin(), m_Set.end(), *itCursor) == m_Set.end())
153             return false;
154
155     // all rooms were found
156     return true;
157 }
158
159
160 // virtual, see operator==
161 bool CHouse::EqualValue(const CBasicClass* pClass) const {
162     // cast to CHouse
163     const CHouse *house = dynamic_cast<const CHouse*>(pClass);
164
165     // invalid class (is NULL when pClass is not a CHouse)
166     if (house == NULL || house == this)
167         return false;
168
169     // use non virtual reference based copy
170     return operator==(*house);
171 }
172
173
174 // return date of foundation
175 CDate CHouse::GetDateOfFoundation() const {
176     return m_dtDateOfFoundation;
177 }
178
179
180 // return number of stored rooms
181 int CHouse::Card() const {
182     return m_Set.size();
183 }
184
185
186 // insert a new room into the set, TRUE if successful
187 // will fail if room already exists
188 bool CHouse::Insert(const CRoom &room)
189 {
190     // room should be valid
191     if (!room.ClassInvariant())
192 // throw CException("CHouse::Insert: invalid room", this);
193         return false;
194        
195     // there must be some memory to grow the set
196     if (m_Set.size() > m_Set.max_size())
197         throw CException("CHouse::Insert: out of memory", this);
198
199     // and the room must not be part of the list
200     if (Find(room))
201         return false;
202
203     // insert at the tail of the list
204     m_Set.insert(room);
205
206     return true;
207 }
208
209
210 // return first stored room, TRUE if successful
211 bool CHouse::GetFirst(CRoom &room)
212 {
213     // set must not be empty
214     if (m_Set.empty())
215 // throw CException("CHouse::GetFirst: empty set", this);
216         return false;
217
218     // set cursor to first room
219     m_itCursor = m_Set.begin();
220     // get this room
221     room = *m_itCursor;
222
223     return true;
224 }
225
226
227 // return next room, TRUE if successful
228 bool CHouse::GetNext(CRoom &room)
229 {
230     // set must not be empty, end must not be reached
231     if (m_Set.empty())
232 // throw CException("CHouse::GetNext: empty set", this);
233         return false;
234
235     if (m_itCursor != m_Set.end())
236 // throw CException("CHouse::GetNext: reached end", this);
237         return false;
238    
239     // iterate to next object
240     m_itCursor++;
241     // get this object
242     room = *m_itCursor;
243
244     return true;
245 }
246
247
248 // look for a room and set cursor, TRUE if successful
249 bool CHouse::Find(const CRoom &room)
250 {
251     // set must not be empty
252     if (m_Set.empty())
253 // throw CException("CHouse::Find: empty set", this);
254         return false;
255
256     // create new iterator
257     TSetCursor itCursor;
258
259     // use STL's find
260     itCursor = std::find(m_Set.begin(), m_Set.end(), room);
261
262     // change m_itCursor if room was found
263     if (itCursor != m_Set.end())
264     {
265         m_itCursor = itCursor;
266         return true;
267     }
268     else         return false;
269 }
270
271
272 // return the room the cursor points to, TRUE if successful
273 bool CHouse::GetCurrent(CRoom &room) const {
274     // set must not be empty
275     if (m_Set.empty())
276         throw CException("CHouse::GetCurrent: empty set", this);
277
278     // return current room
279     room = *m_itCursor;
280     return true;
281 }
282
283
284 // erase current room, TRUE if successful
285 bool CHouse::Scratch()
286 {
287     // set must not be empty
288     if (m_Set.empty())
289         throw CException("CHouse::Scratch: empty set", this);
290
291     // erase room, set cursor to next room
292     m_itCursor = m_Set.erase(m_itCursor);
293     return true;
294 }
295
296
297 // emulates basic iterator independent of those from STL
298 void CHouse::ForEachDo(const TIteratorFunc iteratorProc)
299 {   
300     // save current cursor
301     TSetCursor itCursor = m_itCursor;
302
303     m_itCursor = m_Set.begin();
304     while (m_itCursor != m_Set.end())
305     {
306         CRoom* room = &(*m_itCursor);
307         iteratorProc(room);
308         m_itCursor++;
309     }
310
311     // restore cursor
312     m_itCursor = itCursor;
313 }
314
315
316 // helper
317 static ostringstream _strShow;
318 static void _ShowProc(CRoom* room)
319 {
320     _strShow << room->Show();
321 }
322
323
324 // same functionality as Show, I just use ForEachDo this time
325 string CHouse::ShowUsingForEachDo() const {
326     CHouse* house = const_cast<CHouse*>(this);
327     house->ForEachDo(_ShowProc);
328
329     return _strShow.str();
330 }
331
332