Программирование >>  Дополнительные возможности наследования 

1 ... 140 141 142 [ 143 ] 144 145 146 ... 265


268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303

PartsList&pl = PartsList::GetGlobalPartsList(); Part pPart = 0; int PartNumber; int value; int Choice;

while (1) {

cout (ООиН (l)Car (2)Plane: ; cin choice;

if (Ichoice) break;

cout New PartNumber?: ; cin >> PartNumber;

if (choice == 1) {

cout Model Year?: ; cin >> value;

pPart = new CarPart(value,PartNumber);

else {

cout Engine Number?: ; cin value;

pPart = new AirPlanePart(value,PartNumber);

pi. Insert(pPart);

void (Part: : *pFunc)( )const = Part:: Display;-pi.Iterate(pFunc); return 0;

(O)Quit (l)Car (2)Plane: New PartNumber?: 2837 Model Year? 90 (O)Quit (1)Car (2)Plane: New PartNumber?: 378 Engine Number?: 4938 (O)Quit (l)Car (2)Plane: New PartNumber?: 4499 Model Year? 94 (O)Quit (1)Car (2)Plane: New PartNumber?: 3000 Model Year? 93



(O)Quit (1)Car (2)Plane; 0

Part Number: 378 Engine No.: 4938

Part Number: 2837 Model Year: 90

Part Number: 3000 Model Year: 93

Part Number: 4499 Model Year: 94

Представленная программа создает связанный список объектов класса Part. Связанный список - это динамическая структура данных вроде массива, за исключением того, что в список можно добавлять произвольное число объектов указанного типа и удалять любой из введенных объектов.

Данный связанный список разработан для хранения объектов класса Part, где Part - абстрактный тип данных, служащий базовым классом для любого объекта с заданной переменной-членом ItsPartNumber. В профамме от класса Part производятся два подкласса - CarPart и AirPlanePart.

Класс Part описывается в строках 26-36, где задаются одна переменная-член и несколько методов доступа. Предполагается, что затем в объекты класса будет добавлена другая ценная информация и возможность контроля за числом созданных объектов в базе данных. Класс Part описывается как абстрактный тип данных, на что указывает чистая виртуальная функция DisplayO.

Обратите внимание, что в строках 40-43 определяется выполнение чистой виртуальной функции DisplayO. Предполагается, что метод DisplayO будет замещаться в каждом производном классе, но в определении замещенного варианта допускается просто вызывать стандартный метод из базового класса.

Два простых производных класса, CarPart и AirPlanePart, описываются в строках 47-59 и 69-87 соответственно. В каждом из них замещается метод DisplayO простым обращением к методу DisplayO базового класса.

Класс PartNode выступает в качестве интерфейса между классами Part и Partlist. Он содержит указатель на Part и указатель на следующий узел в списке. Методы этого класса только возвращают и устанавливают следующий узел в списке и возвращают соответствующий объект Part.

За интеллектуальность связанного списка полностью отвечает класс PartsList, описываемый в сфоках 132-152. Этот класс содержит указатель на головной узел списка (pHead) и, с его помощью продвигаясь по списку, получает доступ ко всем другим методам. Продвижение по списку означает запрашивание текущего узла об адресе следующего вплоть до обнаружения узла, указатель которого на следующий узел равен NULL.

Безусловно, в этом примере представлен упрощенный вид связанного списка. В реально используемой программе список должен обеспечивать еще больший доступ к первому и последнему узлам списка или создавать специальный объект итерации, с помощью которого клиенты смогут легко продвигаться по списку.

В то же время класс PartsList предлагает ряд интересных методов, упорядоченных по алфавиту. Зачастую такой подход весьма эффективен, поскольку упрощает поиск нужных функций.



функция FindO принимает в качестве параметров PartNumber и значение int. Если найден раздел с указанным значением PartNumber, функция возвращает указатель на Part и порядковый номер этого раздела в списке. Если же раздел с номером PartNumber не обнаружен, функция возвращает значение NULL.

Функция GetCountO проходит по всем узлам списка и возвращает количество объектов в списке. В PartsList это значение записывается в переменную-член itsCount, хотя его можно легко вычислить, последовательно продвигаясь по списку.

Функция GetFirstO возвращает указатель на первый объект Part в списке или значение NULL, если список пустой.

Функция QetQlobalPartsListO возвращает ссылку на статическую переменную-член GlobalPartsList. Описание статической переменной GlobalPartsList является типичным решением для классов типа PartsList, хотя, безусловно, могут использоваться и другие имена. В законченном виде реализация этой идеи состоит в автоматическом изменении конструктора класса Part таким образом, чтобы каждому новому объекту класса присваивался номер с учетом текущего значения статической переменной GlobalPartsList.

Функция Insert принимает значение указателя на объект Part, создает для него PartNode и добавляет объект Part в список в порядке возрастания номеров PartNumber.

Функция Iterate принимает указатель на константную функцию-член класса Part без параметров, которая возвращает void. Эта функция вызывается для каждого объекта Part в списке. В описании класса Part таким характеристикам соответствует единственная функция DisplayO, замещенная во всех производных классах. Таким образом, будет вызываться вариант метода DisplayO, соответствующий типу объекта Part.

Функция 0perator[] позволяет получить прямой доступ к объекту Part по заданному смещению. Этот метод обеспечивает простейший способ определения границ списка: если список нулевой, или заданное смещение больше числа объектов в списке, возвращается значение NULL, сигнализирующее об ошибке.

В реальной программе имело бы смысл все эти комментарии с описанием назначений функций привести в описании класса.

Тело функции main() представлено в строках 266-303. В строке 268 описывается ссылка на PartsList и инициализируется значением GlobalPartsList. Обратите внимание, что GlobalPartsList инициализируется в строке 154. Эта строка необходима, поскольку описание статической переменной-члена не сопровождается ее автоматическим определением. Поэтому определение статической переменной-члена должно выполняться за пределами описания класса.

В строках 274-299 пользователю предлагается указать, вводится ли деталь для машины или для самолета. В зависимости от выбора, запрашиваются дополнительные сведения и создается новый объект, который добавляется в список в строке 298.

Выполнение метода InsertO класса PartList показано в строках 218-264. При вводе идентификационного номера первой детали - 2837 - создается объект CarPart, который передается в LinkedList: :Insert()c введенными номером детали и годом создания 90.

В строке 220 создается новый объект PartNode, принимающий значения новой детали. Переменная New инициализируется номером детали. Переменная-член itsCount класса PartsList увеличивается на единицу в строке 226.

В строке 228 проверяется равенство указателя pHead значению NULL. В данном случае возвращается значение TRUE, поскольку это первый узел списка и указатель pHead в нем нулевой. В результате в строке 230 указателю pHead присваивается адрес нового узла и функция возвращается.

Пользователю предлагается ввести следующую деталь. В нашем примере вводится деталь от самолета с идентификационным номером 37 и номером двигателя 4938. Сно-



1 ... 140 141 142 [ 143 ] 144 145 146 ... 265

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика