KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Джесс Либерти - Освой самостоятельно С++ за 21 день.

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Джесс Либерти, "Освой самостоятельно С++ за 21 день." бесплатно, без регистрации.
Перейти на страницу:

Подведение итогов

В приведенной ниже программе используются многие "продвинутые" методы, с которыми вы познакомились на протяжении трех недель усердных занятий. Программа содержит связанный список, основанный на шаблоне; кроме того, в ней проводится обработка исключительных ситуаций. Тщательно разберитесь в этой программе, и, если полностью ее поймете, значит, вы — программист C++.


Предупреждение:Если ваш компилятор не поддерживает шаблоны или блоки try и catch, вы не сможете скомпилировать эту программу.


Листинг 3.1. Программа, основанная на материалах недели 3

1:  // ************************************

2:  //

3:  // Название: Обзор недели 3

4:  //

5:  // Файл: Week3

6:  //

7:  // Описание: Программа с использованием связанного списка

8:  // на основе шаблона с обработкой исключительных ситуаций

9:  //

10: // Классы: PART - хранит номера запчастей и потенциально другую

11: // информацию о запчастях. Зто будет

12: // пример класса для хранения списка.

13: // Обратите внимание на использование

14: // оператора << для печати информации о запчасти

15: // на основе его типа и времени выполнения,

16: //

17: //      Node - действует как узел в классе List

18: //

19: //      List - список, основанный на шаблоне, который

20: // обеспечивает работу связанного списка

21: //

22: //

23: // Автор: Jesse Liberty (jl)

24: //

25: // Разработан: Pentium 200 Pro. 128MB RAM MVC 5.0

26: //

27: // Требования: Не зависит от платформы

28: //

29: // История создания: 9/94 - Первый выпуск (jl)

30: //             4/97 - Обновлено (jl)

31: // ************************************

32:

33: #include <iostream.h>

34:

35: // классы исключений

36: class Exception { };

37: class OutOfMemory : public Exception{ };

38: class NullNode : public Exception{ };

39: class EmptyList : public Exception { };

40: class BoundsError : public Exception { };

41:

42:

43: // **************** Part **************

44: // Абстрактный базовый класс запчастей

45: class Part

46: {

47:    public:

48:       Part():its0bjectNumber(1) { }

49:       Part(int 0bjectNumber):its0bjectNumber(ObjectNumber){ }

50:       virtual ~Part(){ };

51:       int GetObjectNumber() const { return itsObjectNumber; }

52:       virtual void Display() const =0; // функция будет замещена в производном классе

53:

54:    private:

55:       int itsObjectNumber;

56: };

57:

58: // выполнение чистой виртуальной функции, необходимой

59: // для связывания объектов производного класса

60: void Part::Display() const

61: {

62:    cout << "nPart Number: " << itsObjectNumber << endl;

63: }

64:

65: // Этот оператор << будет вызываться для всех объектов запчастей.

66: // Его не нужно объявлять другом, поскольку он не обращается к закрытым данным.

67: // Он вызывает метод Display(), в результате чего реализуется полиморфизм классов.

68: // Было бы не плохо замещать функцию оператора для разных

69: // типов thePart, но C++ не поддерживает контравариантность

70: ostream& operator<<( ostream& theStream,Part& thePart)

71: {

72:    thePart.Display(); // косвенная реализация полиморфизма оператора вывода!

73:    return theStream;

74: }

75:

76: // **************** Car Part ************

77: class CarPart : public Part

78: {

79:    public:

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

81:       CarPart(int year, int partNumber);

82:       int GetModelYear() const { return itsModelYear; }

83:       virtual void Display() const;

84:    private:

85:       int itsModelYear;

86: };

87:

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

89: itsModelYear(year),

90: Part(partNumber)

91: { }

92:

93: void CarPart::Display() const

94: {

95:    Part::Display();

96:    cout << "Model Year: " << itsModelYear << endl;

97: }

98:

99:  // **************** AirPlane Part ************

100: class AirPlanePart : public Part

101: {

102:    public:

103:       AirPlanePart():itsEngineNumber(1){ } ;

104:       AirPlanePart(int EngineNumber, int PartNumber);

105:       virtual void Display() const;

106:       int GetEngineNumber()const { return itsEngineNumber; }

107:    private:

108:       int itsEngineNumber;

109: };

110:

111: AirPlanePart::AirPlanePart(int EngineNumber, int PartNumber):

112: itsEngineNumber(EngineNumber),

113: Part(PartNumber)

114: { }

115:

116: void AirPlanePart::Display() const

117: {

118:    Part::Display();

119:    cout << "Engine No,: " << itsEngineNumber << endl;

120: }

121:

122: // Обьявление класса List

123: template <class T>

124: class List;

125:

126: // **************** Node ************

127: // Общий узел, который можно добавить к списку

128: // **********************************

129:

130: template <class T>

131: class Node

132: {

133:    public:

134:       friend class List<T>;

135:       Node (T*);

136:       ~Node();

137:       void SetNext(Node * node) { itsNext = node; }

138:       Node * GetNext() const;

139:       T * GetObject() const;

140:    private:

141:       T* its0bject;

142:       Node * itsNext;

143: };

144:

145: // Выполнение узла...

146:

147: template <class T>

148: Node<T>::Node(T* p0jbect):

149: itsObject(pOjbect),

150: itsNext(0)

151: { }

152:

153: template <class T>

154: Node<T>::~Node()

155: {

156:    delete its0bject;

157:    itsObject = 0;

158:    delete itsNext;

159:    itsNext = 0;

160: }

161:

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

163: template <class T>

164: Node<T> * Node<T>::GetNext() const

165: {

166:    return itsNext;

167: }

168:

169: template <class T>

170: T * Node<T>::GetObject() const

171: {

172:    if (itsObject)

173:       return itsObject;

174:    else

175:       throw NullNode();

176: }

177:

178: // **************** List ************

179: // Общий шаблон списка

180: // Работает с любым нумерованным объектом

181: // **********************************

182: template <olass T>

183: class List

184: {

185:    public:

186:       List();

187:       ~List();

188:

189:       T* Find(int & position, int 0bjectNumber) const;

190:       T* GetFirst() const;

191:       void Insert(T *);

192:       T* operator[](int) const;

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

194:    private:

195:       Node<T> * pHead;

196:       int itsCount;

197: };

198:

199: // Выполнение списка...

200: template <class T>

201: List<T>::List();

202: pHead(0),

203: itsCount(0)

204: { }

205:

206: template <class T>

207: List<T>::~List()

208: {

209:    delete pHead;

210: }

211:

212: template <class T>

213: T* List<T>::GetFirst() const

214: {

215:    if (pHead)

216:       return pHead->itsObject;

217:    else

218:       throw EmptyList();

219: }

220:

221: template <class T>

222: T * List<T>::operator[](int offSet) const

223: {

224:    Node<T>* pNode = pHead;

225:

226:    if (!pHead)

227:       throw EmptyList();

228:

229:    if (offSet > itsCount)

230:       throw BoundsError();

231:

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

233:       pNode = pNode->itsNext;

234:

235:    return pNode->itsObject;

236: }

237:

238: // Находим данный обьект в списке на основе его идентификационного номера (id)

239: template <class T>

240: T* List<T>::Find(int & position, int 0bjectNumber) const

241: {

242:    Node<T> * pNode = 0;

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

244:         pNode!=NULL;

245:         pNode = pNode->itsNext, position++)

246:    {

247:       if (pNode->itsObject->GetObjectNumber() == 0bjectNumber)

248:          break;

249:    }

250:    if (pNode == NULL)

251:       return NULL;

252:    else

253:       return pNode->itsObject;

254: }

255:

256: // добавляем в список, если номер объекта уникален

257: template <class T>

258: void List<T>::Insert(T* pObject)

259: {

260:    Node<T> * pNode = new Node<T>(p0bject);

261:    Node<T> * pCurrent = pHead;

262:    Node<T> * pNext = 0;

263:

264:    int New = p0bject->Get0bjectNumber();

265:    int Next = 0;

266:    itsCount++;

267:

268:    if (!pHead)

269:    {

270:       pHead = pNode;

271:       return;

272:    }

273:

274:    // если номер текущего объекта меньше номера головного,

275:    // то этот объект становится новым головным узлом

276:    if (pHead->itsObject->GetObjectNumber() > New)

277:    {

278:       pNode->itsNext = pHead;

279:       pHead = pNode;

280:       return;

281:    }

282:

283:    for (;;)

284:    {

285:       // если нет следующего обьекта, добавляем в конец текущий объект

286:       if (!pCurrent->itsNext)

287:       {

288:          pCurrent->itsNext = pNode;

289:          return;

290:       }

291:

292:       // если данный объект больше текущего, но меньше следующего,

293:       // то вставляем его между ними, в противном случае переходим к следующему объекту

294:       pNext = pCurrent->itsNext;

295:       Next = pNext->itsObject->GetObjectNumber();

296:       if (Next > New)

297:       {

298:          pCurrent->itsNext = pNode;

299:          pNode->itsNext = pNext;

300:          return;

301:       }

302:       pCurrent = pNext;

303:    }

304: }

305:

306:

307: int main()

308: {

309:    List<Part> theList;

310:    int choice;

311:    int ObjectNumber;

312:    int value;

313:    Part * pPart;

314:    while (1)

315:    {

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

317:       cin >> choice;

318:

319:       if (!choice)

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*