Рейтинговые книги
Читем онлайн Освой самостоятельно С++ за 21 день. - Джесс Либерти

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 97 98 99 100 101 102 103 104 105 ... 170

Попробуем сначала решить эту задачу путем вложения одного класса в другой с делегированием ответственности от класса классу, как показано в листинге 15.5.

Листинг 15.5. Делегирование ответственности классу PartsList, включенному в класс PartsCatalog

1: #include <iostream.h>

2:

3: // **************** Класс Part ************

4:

5: // Абстрактный базовый класс всех деталей

6: class Part

7: {

8:    public:

9:       Part():itsPartNumber(1) { }

10:      Part(int PartNumber):

11:         itsPartNumber(PartNumber){ }

12:      virtual ~Part(){ }

13:      int GetPartNumber() const

14:         { return itsPartNumber; }

15:      virtual void Display() const =0;

16:   private:

17:      int itsPartNumber;

18: };

19:

20: // выполнение чистой виртуальной функции в

21: // стандартном виде для всех производных классов

22: void Part::Display() const

23: {

24:    cout << "nPart Number: " << itsPartNumber << endl;

25: }

26:

27: // ************ Автомобильные детали **********

28:

29: class CarPart : public Part

30: {

31:    public:

32:       CarPart():itsModelYear(94){ }

33:       CarPart(int year, int partNumber);

34:       virtual void Display() const

35:       {

36:          Part::Display();

37:          cout << "Model Year: ";

38:          cout << itsModelYear << endl;

39:       }

40:    private:

41:       int itsModelYear;

42: };

43:

44: CarPart::CarPart(int year, int partNumber):

45:    itsModelYear(year),

46:    Part(partNumber)

47: { }

48:

49:

50: // ************* Авиационные детали ************

51:

52: class AirPlanePart : public Part

53: {

54:    public:

55:       AirPlanePart():itsEngineNumber(1){ }

56:       AirPlanePart

57:          (int EngineNumber, int PartNumber)

58:       virtual void Dlsplay() const

59:       {

60:          Part::Display();

61:          cout << " Engine No.: ";

62:          cout << itsEngineNumber << endl;

63:       }

64:    private:

65:       int itsEngineNumber;

66: };

67:

68: AirPlanePart::AirPlanePart

69:    (int EngineNumber, int PartNumber):

70:       itsEngineNumber(EngineNumber),

71:       Part(PartNumber)

72: { }

73:

74: // *************** Узлы списка деталей **********

75: class PartNode

76: {

77:    public:

78:       PartNode (Part*);

79:       ~PartNode();

80:       void SetNext(PartNode * node)

81:          { itsNext = node; }

82:       PartNode * GetNext() const;

83:       Part * GetPart() const;

84:    private:

85:       Part *itsPart;

86:       PartNode * itsNext;

87: };

88: // Выполнение PartNode...

89:

90: PartNode::PartNode(Part* pPart):

91:    itsPart(pPart),

92:    itsNext(0)

93: { }

94:

95: PartNode::~PartNode()

96: {

97:    delete itsPart;

98:    itsPart = 0;

99:    delete itsNext;

100:   itsNext = 0;

101: }

102:

103: // Возвращается NULL, если нет следующего узла PartNode

104: PartNode * PartNode::GetNext() const

105: {

106:    return itsNext;

107: }

108:

109: Part * PartNode::GetPart() const

110: {

111:    if (itsPart)

112:       return itsPart;

113:    else

114:       return NULL; //ошибка

115: }

116:

117:

118:

119: // **************** Список деталей ***********

120: class PartsList

121: {

122:    public:

123:       PartsList();

124:       ~PartsList();

125:       // необходимо, чтобы конструктор-копировщик и оператор соответствовали друг другу!

126:       void Iterate(void (Part::*f)()const) const;

127:       Part* Find(int & position, int PartNumber) const;

128:       Part* GetFirst() const;

129:       void Insert(Part *);

130:       Part* operator[](int) const;

131:       int GetCount() const { return itsCount;}

132:       static PartsList& GetGlobalPartsList()

133:       {

134:          return GiobalPartsList;

135:       }

136:    private:

137:       PartNode * pHead;

138:       int itsCount;

139:       static PartsList GiobalPartsList;

140: };

141:

142: PartsList PartsList::GlobalPartsList;

143:

144:

145: PartsList::PartsList():

146:    pHead(0),

147:    itsCount(0)

148: { }

149:

150: PartsList::~PartsList()

151: {

152:    delete pHead;

153: }

154:

155: Part* PartsList::GetFirst() const

156: {

157:    if (pHead)

158:       return pHead->GetPart();

159:    else

160:       return NULL; // ловушка ошибок

161: }

162:

163: Part * PartsList::operator[](int offSet) const

164: {

165:    PartNode* pNode = pHead;

166:

167:    if (!pHead)

168:       return NULL; // ловушка ошибок

169:

170:    if (offSet > itsCount)

171:       return NULL; // ошибка

172:

173:    for (int i=0;i<offSet; i++)

174:       pNode = pNode->GetNext();

175:

176:    return pNode->GetPart();

177: }

178:

179: Part* PartsList::Find( 

180:    int & position,

181:    int PartNumber) const

182: {

183:    PartNode * pNode = 0;

184:    for (pNode = pHead, position = 0;

185:       pNode!=NULL;

186:       pNode = pNode->GetNext(), position++)

187:    {

188:       if (pNode->GetPart()->GetPartNumber()== PartNumber)

189:          break;

190:    }

191:    if (pNode == NULL)

192:       return NULL;

193:    else

194:       return pNode->GetPart();

195: }

196:

197: void PartsList::Iterate(void (Part::*func)()const) const

198: {

199:    if (!pHead)

200:       return;

201:    PartNode* pNode = pHead;

202:    do

203:       (pNode->GetPart()->*func)();

204:    while (pNode = pNode->GetNext());

205: }

206:

207: void PartsList::Insert(Part* pPart)

208: {

209:    PartNode * pNode = new PartNode(pPart);

210:    PartNode * pCurrent - pHead;

211:    PartNode * pNext = 0;

212:

213:    int New = pPart->GetPartNumber();

214:    int Next = 0;

215:    itsCount++;

216:

217:    if (!pHead)

218:    {

219:       pHead = pNode;

220:       return;

221:    }

222:

223:    // если это значение меньше головного узла,

224:    // то текущий узел становится головным

225:    if (pHead->GetPart()->GetPartNumber()->New)

226:    {

227:       pNode->SetNext(pHead);

228:       pHead = pNode;

229:       return;

230:    }

231:

232:    for (;;)

233:    {

234:       // если нет следующего, вставляется текущий

235:       if (!pCurrent->GetNext())

236:       {

237:          pCurrent->SetNext(pNode);

238:          return;

239:       }

240:

241:       // если текущий больше предыдущего, но меньше следующего, то вставляем

242:       // здесь. Иначе присваиваем значение указателя Next

243:       pNext = pCurrent->GetNext();

244:       Next = pNext->GetPart()->GetPartNumber();

245:       if (Next > New)

246:       {

247:          pCurrent->SetNext(pNode);

248:          pNode->SetNext(pNext);

249:          return;

250:       }

251:       pCurrent = pNext;

252:    }

253: }

254:

255:

256:

257: class PartsCatalog

258: {

259:    public:

260:       void Insert(Part *);

261:       int Exists(int PartNumber);

262:       Part * Get(int PartNumber);

263:       operator+(const PartsCatalog &);

264:       void ShowAll() { thePartsList.Iterate(Part::Display); }

265:    private:

266:       PartsList thePartsList;

267: };

268:

269: void PartsCatalog::Insert(Part * newPart)

270: {

271:    int partNumber = newPart->GetPartNumber();

272:    int offset;

273:

274:    if (!thePartsList,Find(offset, partNumber))

275:      

276:       thePartsList.Insert(newPart);

277:    else

278:    {

279:       cout << partNumber << " был ";

280:       switch (offset)

281:       {

282:          case 0: cout << "first "; break;

283:          case 1: cout << "second "; break;

284:          case 2: cout << "third "; break;

285:          default; cout << offset+1 << "th ";

286:       }

287:       cout << "entry. Rejected!n";

288:    }

289: }

290:

291: int PartsCatalog::Exists(int PartNumber)

292: {

293:    int offset;

294:    thePartsList.Find(offset,PartNumber);

295:    return offset;

296: }

297:

298: Part * PartsCatalog::Get(int PartNumber)

299: {

300:    int offset;

301:    Part * thePart = thePartsList.Find(offset, PartNumber);

302:    return thePart;

303: }

304:

305:

306: int main()

307: {

308:    PartsCatalog pc;

309:    Part * pPart = 0;

310:    int PartNumber;

311:    int value;

312:    int choice;

313:

314:    while (1)

315:    {

316:       cout << "(0)Quit (1)Car (2)Plane: ";

317:       cin >> choice;

318:

319:       if (!choice)

320:          break;

321:

322:       cout << "New PartNumber?: ";

323:       cin >> PartNumber;

324:

325:       if (choice == 1)

326:       {

327:          cout << "Model Year?: ";

328:          cin >> value;

329:          pPart = new CarPart(value,PartNumber);

330:       }

331:       else

332:       {

333:          cout << "Engine Number?: ";

334:          cin >> value;

335:          pPart = new AirPlanePart(value,PartNumber);

335:       }

337:       pc.Insart(pPart);

338:    }

339:    pc.ShowAli();

340:    return 0;

341: }

Результат:

(0)Qult (1)Car (2)Plane: 1

New PartNumber?: 1234

Model Year?: 94

(0)Quit (1)Car (2)Plane: 1

New PartNumber?: 4434

Model Year?: 93

(0)Quit (1)Car (2)Plane: 1

New PartNumber?: 1234

Model Year?: 94

1234 was the first entry. Rejected!

(0)Quit (1)Car (2)Plane: 1

New PartNumber?: 2345

Model Year?: 93

(0)Quit (1)Car (2)Plane: 0

Part Number: 1234

1 ... 97 98 99 100 101 102 103 104 105 ... 170
На этой странице вы можете бесплатно читать книгу Освой самостоятельно С++ за 21 день. - Джесс Либерти бесплатно.

Оставить комментарий