📄 ch15.htm
字号:
<P>Certainly it would have been possible to inherit publicly from <TT>PartsList</TT>
and then override <TT>Insert()</TT> and the offset operators (<TT>[]</TT>) to do
the right thing, but then you would have changed the essence of the <TT>PartsList</TT>
class. Instead you'll build a <TT>PartsCatalog</TT> that has no offset operator,
does not allow duplicates, and defines the <TT>operator+</TT> to combine two sets.</P>
<P>The first way to accomplish this is with containment. The <TT>PartsCatalog</TT>
will delegate list management to a contained <TT>LinkedList</TT>. Listing 15.5 illustrates
this approach.</P>
<P><A NAME="Heading18"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 15.5. Delegating
to a contained LinkedList.</B></FONT>
<PRE><FONT COLOR="#0066FF">0: #include <iostream.h>
1:
2: typedef unsigned long ULONG;
3: typedef unsigned short USHORT;
4:
5:
6: // **************** Part ************
7:
8: // Abstract base class of parts
9: class Part
10: {
11: public:
12: Part():itsPartNumber(1) {}
13: Part(ULONG PartNumber):
14: itsPartNumber(PartNumber){}
15: virtual ~Part(){}
16: ULONG GetPartNumber() const
17: { return itsPartNumber; }
18: virtual void Display() const =0;
19: private:
20: ULONG itsPartNumber;
21: };
22:
23: // implementation of pure virtual function so that
24: // derived classes can chain up
25: void Part::Display() const
26: {
27: cout << "\nPart Number: " << itsPartNumber << endl;
28: }
29:
30: // **************** Car Part ************
31:
32: class CarPart : public Part
33: {
34: public:
35: CarPart():itsModelYear(94){}
36: CarPart(USHORT year, ULONG partNumber);
37: virtual void Display() const
38: {
39: Part::Display();
40: cout << "Model Year: ";
41: cout << itsModelYear << endl;
42: }
43: private:
44: USHORT itsModelYear;
45: };
46:
47: CarPart::CarPart(USHORT year, ULONG partNumber):
48: itsModelYear(year),
49: Part(partNumber)
50: {}
51:
52:
53: // **************** AirPlane Part ************
54:
55: class AirPlanePart : public Part
56: {
57: public:
58: AirPlanePart():itsEngineNumber(1){};
59: AirPlanePart
60: (USHORT EngineNumber, ULONG PartNumber);
61: virtual void Display() const
62: {
63: Part::Display();
64: cout << "Engine No.: ";
65: cout << itsEngineNumber << endl;
66: }
67: private:
68: USHORT itsEngineNumber;
69: };
70:
71: AirPlanePart::AirPlanePart
72: (USHORT EngineNumber, ULONG PartNumber):
73: itsEngineNumber(EngineNumber),
74: Part(PartNumber)
75: {}
76:
77: // **************** Part Node ************
78: class PartNode
79: {
80: public:
81: PartNode (Part*);
82: ~PartNode();
83: void SetNext(PartNode * node)
84: { itsNext = node; }
85: PartNode * GetNext() const;
86: Part * GetPart() const;
87: private:
88: Part *itsPart;
89: PartNode * itsNext;
90: };
91: // PartNode Implementations...
92:
93: PartNode::PartNode(Part* pPart):
94: itsPart(pPart),
95: itsNext(0)
96: {}
97:
98: PartNode::~PartNode()
99: {
100: delete itsPart;
101: itsPart = 0;
102: delete itsNext;
103: itsNext = 0;
104: }
105:
106: // Returns NULL if no next PartNode
107: PartNode * PartNode::GetNext() const
108: {
109: return itsNext;
110: }
111:
112: Part * PartNode::GetPart() const
113: {
114: if (itsPart)
115: return itsPart;
116: else
117: return NULL; //error
118: }
119:
120:
121:
122: // **************** Part List ************
123: class PartsList
124: {
125: public:
126: PartsList();
127: ~PartsList();
128: // needs copy constructor and operator equals!
129: void Iterate(void (Part::*f)()const) const;
130: Part* Find(ULONG & position, ULONG PartNumber) const;
131: Part* GetFirst() const;
132: void Insert(Part *);
133: Part* operator[](ULONG) const;
134: ULONG GetCount() const { return itsCount; }
135: static PartsList& GetGlobalPartsList()
136: {
137: return GlobalPartsList;
138: }
139: private:
140: PartNode * pHead;
141: ULONG itsCount;
142: static PartsList GlobalPartsList;
143: };
144:
145: PartsList PartsList::GlobalPartsList;
146:
147:
148: PartsList::PartsList():
149: pHead(0),
150: itsCount(0)
151: {}
152:
153: PartsList::~PartsList()
154: {
155: delete pHead;
156: }
157:
158: Part* PartsList::GetFirst() const
159: {
160: if (pHead)
161: return pHead->GetPart();
162: else
163: return NULL; // error catch here
164: }
165:
166: Part * PartsList::operator[](ULONG offSet) const
167: {
168: PartNode* pNode = pHead;
169:
170: if (!pHead)
171: return NULL; // error catch here
172:
173: if (offSet > itsCount)
174: return NULL; // error
175:
176: for (ULONG i=0;i<offSet; i++)
177: pNode = pNode->GetNext();
178:
179: return pNode->GetPart();
180: }
181:
182: Part* PartsList::Find(
183: ULONG & position,
184: ULONG PartNumber) const
185: {
186: PartNode * pNode = 0;
187: for (pNode = pHead, position = 0;
188: pNode!=NULL;
189: pNode = pNode->GetNext(), position++)
190: {
191: if (pNode->GetPart()->GetPartNumber() == PartNumber)
192: break;
193: }
194: if (pNode == NULL)
195: return NULL;
196: else
197: return pNode->GetPart();
198: }
199:
200: void PartsList::Iterate(void (Part::*func)()const) const
201: {
202: if (!pHead)
203: return;
204: PartNode* pNode = pHead;
205: do
206: (pNode->GetPart()->*func)();
207: while (pNode = pNode->GetNext());
208: }
209:
210: void PartsList::Insert(Part* pPart)
211: {
212: PartNode * pNode = new PartNode(pPart);
213: PartNode * pCurrent = pHead;
214: PartNode * pNext = 0;
215:
216: ULONG New = pPart->GetPartNumber();
217: ULONG Next = 0;
218: itsCount++;
219:
220: if (!pHead)
221: {
222: pHead = pNode;
223: return;
224: }
225:
226: // if this one is smaller than head
227: // this one is the new head
228: if (pHead->GetPart()->GetPartNumber() > New)
229: {
230: pNode->SetNext(pHead);
231: pHead = pNode;
232: return;
233: }
234:
235: for (;;)
236: {
237: // if there is no next, append this new one
238: if (!pCurrent->GetNext())
239: {
240: pCurrent->SetNext(pNode);
241: return;
242: }
243:
244: // if this goes after this one and before the next
245: // then insert it here, otherwise get the next
246: pNext = pCurrent->GetNext();
247: Next = pNext->GetPart()->GetPartNumber();
248: if (Next > New)
249: {
250: pCurrent->SetNext(pNode);
251: pNode->SetNext(pNext);
252: return;
253: }
254: pCurrent = pNext;
255: }
256: }
257:
258:
259:
260: class PartsCatalog
261: {
262: public:
263: void Insert(Part *);
264: ULONG Exists(ULONG PartNumber);
265: Part * Get(int PartNumber);
266: operator+(const PartsCatalog &);
267: void ShowAll() { thePartsList.Iterate(Part::Display); }
268: private:
269: PartsList thePartsList;
270: };
271:
272: void PartsCatalog::Insert(Part * newPart)
273: {
274: ULONG partNumber = newPart->GetPartNumber();
275: ULONG offset;
276:
277: if (!thePartsList.Find(offset, partNumber))
278:
279: thePartsList.Insert(newPart);
280: else
281: {
282: cout << partNumber << " was the ";
283: switch (offset)
284: {
285: case 0: cout << "first "; break;
286: case 1: cout << "second "; break;
287: case 2: cout << "third "; break;
288: default: cout << offset+1 << "th ";
289: }
290: cout << "entry. Rejected!\n";
291: }
292: }
293:
294: ULONG PartsCatalog::Exists(ULONG PartNumber)
295: {
296: ULONG offset;
297: thePartsList.Find(offset,PartNumber);
298: return offset;
299: }
300:
301: Part * PartsCatalog::Get(int PartNumber)
302: {
303: ULONG offset;
304: Part * thePart = thePartsList.Find(offset, PartNumber);
305: return thePart;
306: }
307:
308:
309: int main()
310: {
311: PartsCatalog pc;
312: Part * pPart = 0;
313: ULONG PartNumber;
314: USHORT value;
315: ULONG choice;
316:
317: while (1)
318: {
319: cout << "(0)Quit (1)Car (2)Plane: ";
320: cin >> choice;
321:
322: if (!choice)
323: break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -