[3] является довольно популярным базовым классом, на котором построено множество других классов. Рассмотрим реализацию класса списка.
//********************************//
// Программа для обработки объектов//
// классов "список", "двусвязный //
// список", "закольцованный список" //
//-------------------------------------------------//
// Автор: Каширин Д.И. //
//------------------------------------------//
// Версия: 07.12.02 v. 1.01.2 //
//
//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <alloc.h>
#include <conio.h>
#define IMAX 4List{ // Класс "Список":Value; // Значение эл-та списка*Next; // @ след. эл-та списка:AddElList(char);OutpList(char);DelElList(int);AddElList(float, char);CreateList();(const char *Ident) // Конструктор класса
{<< "Lead the value of the first "; //Запрос на ввод
// значения<< "element of list "<<Ident<<'\n';>> Value; // Чтение первого эл-та= NULL; // 1-й эл-т ссылается на NULL
}() // Конструктор без параметров
{= 0; // Чтение значения нов. эл-та= NULL; // Нов. эл-т ссыл-ся на NULL
}
~List(); // Деструктор класса
};
//--------------------------------//
// Деструктор класса List //
//--------------------------------//::~List()
{*CurrEl, // Текущий эл-т списка
*TNext; // Следующий эл-т= this; // Первый эл-т - Объект((CurrEl->Next!= NULL) &&
(CurrEl->Next!= this)){= CurrEl->Next; // Сохраним адрес след. эл-та(CurrEl);= TNext; // След. эл-т сделать текущим
};(CurrEl); // Удалить последний эл-т<< "Object deleted" << '\n';();
}
//*****************************************************//
// Функция добавления элемента в конец односвязного списка //
//*****************************************************//List::AddElList(char R)
{*CurrEl, // Текущий эл-т списка
*NewEl = new List; // Новый эл-т списка
// Выдел-е памяти под нов. эл-т= this; // Текущий эл-т - Объект* KeyWord;= R ? this: NULL;(CurrEl->Next!= KeyWord){ // Переход в конец списка= CurrEl->Next;
}<< "Lead the value of new element of list ";>> NewEl->Value; // Ввод знач-я нового эл-та>Next = KeyWord; // Новый эл-т ссылается на NULL>Next = NewEl; // Новый эл-т - в конец списка
}
//----------------------------------------------------------------//
// Функция вывода на экран односвязного списка //
//----------------------------------------------------------------//List::OutpList(char R)
{Count = 1; // Счетчик эл-тов списка*CurrEl; // Текущий эл-т списка= this; // Текущий эл-т - Объект* KeyWord;= R ? this: NULL;(CurrEl!= KeyWord){<< Count << "-th element of list = "; // Вывод эл-та списка<< CurrEl->Value << '\n';= CurrEl->Next;++;
}
}
//-----------------------------------------------------//
// Функция удаления i-го элемента списка //
//-----------------------------------------------------//List::DelElList(int i)
{Count = 1; // Счетчик эл-тов списка*CurrEl, // Текущий эл-т списка
*PrevEl; // Предыдущий эл-т= this; // Текущий эл-т - Объект(Count < i){ // Преход к i-му эл-ту= CurrEl; // Сохранение пред. эл-та= CurrEl->Next;++;
}
//--------------------------------------------------------------//
// Функция добавления элемента в конец списка //
// с заданием элемента из программы //
//--------------------------------------------------------------//List::AddElList(float Val, char R)
{*CurrEl,
*NewEl = new List;= this; // Текущий эл-т - Объект* KeyWord;= R ? this: NULL;(CurrEl->Next!= KeyWord){ // Переход в конец списка= CurrEl->Next;
}>Next = NewEl; // Новый эл-т - в конец списка>Value = Val; // Ввод знач-я нового эл-та>Next = KeyWord; // Новый эл-т ссылается на NULL
}
//----------------------------------------------------------------//
// Функция создания списка (ввод первого эл-та //
// списка, созд. конструктором без параметров) //
//-----------------------------------------------------------------//List::CreateList()
{*CurrEl;ch;Ok = 0;= this; // Текущий эл-т - Объект((Value == 0)||(Ok == 1)){<< "Lead the value of the first "; //Запрос на ввод
// значения<< "element of new list "<<'\n';>> CurrEl->Value;;
}{<< "This List already exists.";<< "Do you want to delete it?(Y/N)";>> ch;((ch == 'N')||(ch == 'n'));((ch == 'Y')||(ch == 'y'))= 1;<< "Input Error";
}(1);
}
//---------------------------------------------------------------------------
//-------------------------------------//
// Производный класс: //
// двусвязный список //
//-------------------------------------//DLList: public List{*Prev; // Адрес пред. эл-та списка:(): List(){= NULL;
}AddElList();DelElList(int);AddElList(float);
};
//------------------------------------------------------------------------------//
// Функция добавления элемента в конец двусвязного списка //
//------------------------------------------------------------------------------//DLList::AddElList()
{*CurrEl, // Текущий эл-т списка
*NewEl = new DLList; // Новый эл-т списка
// Выдел-е памяти под нов. эл-т= this; // Текущий эл-т - Объект(CurrEl->Next!= NULL){ // Переход в конец списка= (DLList*) CurrEl->Next;
}<< "Lead the value of new element of list ";>> NewEl->Value; // Ввод знач-я нового эл-та>Next = NULL; // Новый эл-т ссылается на NULL>Next = NewEl; // Новый эл-т - в конец списка>Prev = CurrEl; // Новый эл-т ссыл-ся на пред.
}
//----------------------------------------------------------------------//
// Функция удаления i-го элемента двусвязного списка //
//----------------------------------------------------------------------//DLList::DelElList(int i)
{Count = 1; // Счетчик эл-тов списка*CurrEl, // Текущий эл-т списка
*PrevEl; // Предыдущий эл-т= this; // Текущий эл-т - Объект(Count < i){ // Преход к i-му эл-ту= CurrEl; // Сохранение пред. эл-та= (DLList*) CurrEl->Next;++;
}>Next = (DLList*) CurrEl->Next; // Пред. эл-т
// ссыл-ся на след.= (DLList*) PrevEl->Next;>Prev = CurrEl->Prev; // След. эл-т ссыл-ся на пред.(CurrEl);
}
//------------------------------------------------------------------//
// Функция добавления элемента в конец списка //
// (двусвязного) с заданием элемента из программы //
//------------------------------------------------------------------//DLList::AddElList(float Val)
{*CurrEl,
*NewEl = new DLList;= this; // Текущий эл-т - Объект(CurrEl->Next!= NULL){ // Переход в конец списка= (DLList*) CurrEl->Next;
}>Next = NewEl; // Новый эл-т - в конец списка>Value = Val; // Ввод знач-я нового эл-та>Next = NULL; // Новый эл-т ссылается на NULL
}
//---------------------------------------------------------------------------
//---------------------------------------//
// Производный класс: //
// закольцованный список //
//---------------------------------------//RLList: public List{:(){= 0;= this;
}
};
//---------------------------------------------------------------------------
// Главная функция программы тестирует работоспособность
// Класса Списокmain(int argc, char **argv)
{TestL;Number;ch = 'Y'; // Вспомогательная перем-яKey = ' ', *PKey;
// Приветствие<< "Hellow! You have ran the program of";<< " processing Lists just now." << '\n';<< "First part:" << '\n';<< "Please, enter you choose:" << '\n';= &Key;
// Главное меню{<< " 1 - New List" << '\n';<< " 2 - Adding Element to List" << '\n';<< " 3 - Deleting Element of List" << '\n';<< " 4 - Output List to screen" << '\n';<< " 5 - Exit" << '\n';= getch();(Key){'1': TestL.CreateList(); break;'2': TestL.AddElList(0); break;'3': cout << "Enter the number of element";<< " you want to delete" << '\n';>> Number;.DelElList(Number); break;'4': TestL.OutpList(0); break;'5': break;: cout << "Input Error";
}(PKey,1,1,stdin);(Key == '5');();
}(1);();<< "Second part:" << '\n';L1("L1"); // Объект - список{((ch == 'Y')||(ch == 'y')).AddElList(0); // Добавление эл-та<< "Input error" << '\n'; // Нажата не та клавиша<< "Do you want to add one"; // Запрос на ввод след. эл-та<< " more element?(Y/N)" << '\n';>> ch;((ch == 'N')||(ch == 'n')); // Выход из цикла
}(1); // Бесконечный цикл.AddElList(12, 0);.OutpList(0); // Вывод сп-ка на экран();();<< "Third part:" << '\n';L2;i;.CreateList();(i = 0; i <= IMAX; i++){.AddElList((float) i+1, 0);
}.OutpList(0); // Вывод сп-ка на экран();0;
}
//---------------------------------------------------------------------------
В приведенном примере определяется базовый класс односвязного списка List в соответствии с концепцией полны класса содержащий все основные функции работы со списками: AddElList(char) - добавление элемента,OutpList(char) - вывод содержимого мписка на экран,DelElList(int) - удаление элемента,CreateList() - первоначальное создание списка.
Как следует из теста программы, класс двусвязного списка DLList является производным классом от List. Такая реализация целесообразна вследствие того, что большинство методов односвязного списка полностью по программному коду совпадают с методами двусвязного, хотя обработка двусвязного списка должна быть дополнена рассмотрением обратных ссылок на элементы. Аналогичным образом реализуется и класс закольцованного списка RLList, по тем же соображениям являющийся производным от класса List.
Для всех классов, описанных в данном примере, используется один и тот же деструктор. Он наследуется производными классами как обычная функция-член, и следовательно будет работать правильно с любыми их объектами, несмотря на различия по числу и размеру полей.
Функция main() в примере предназначена лишь для проверки работоспособности определенных в программе классов и поэтому содержит описание необходимого объекта и меню для его тестирования. При желании число объектов в основной части программы можно пополнить.
Заключение
Объекты в программе работают как слаженный коллектив вполне самостоятельных программ, которые сами знают, когда им в зависимости от текущей ситуации нужно начать работу, когда ее временно приостановить, и наконец, когда совсем покинуть коллектив программ, не оставив о себе никакого воспоминания кроме необходимых полезных результатов работы. Как правило, каждый объект, начиная свою работу, заказывает у операционной системы оперативную память под свои данные, а заканчивая работу, возвращает эту память назад системе. Тем самым оптимизируется объем памяти, занимаемый всей программой в процессе ее работы.
Для того, чтобы объекты четко знали свое место и полномочия в едином коллективе, и не выполняли одну и ту же работу, они подвергаются специальной классификации, результатом которой является выделение классов объектов. Если два класса обладают общими свойствами, значит для них должен существовать более общий класс, который имеет только те свойства, которые для этих двух объектов являются общими. В этом случае объектам классов с общими свойствами нужно заботиться только о выполнении своих функций, связанных с их различающимися свойствами. Общую же часть может выполнить объект более общего класса.
Современные языки программирования, такие как С++, предоставляют в распоряжение программиста обширный арсенал инструментальных средств, позволяющий проектировать мощные и гибкие программы, но для того, что бы приступить к их составлению, необходимо владеть системой элементов объектно-ориентированной технологии. Этой системе элементов для языка С++ и посвящен настоящий раздел книги.
Список литературы
1.М.Уэйт, С.Прата, Д.Мартин Язык Си: Пер с англ.-М.: Мир, 2007.-463 с.,ил.
2.Уинер Р. Язык Турбо Си: Пер с англ.-М.: Мир, 2010.-384 с.,ил.
.В.В. Подбельский. Язык C++: Учебное пособие. - Москва: Финансы и статистика, 199 560с.
.Ирэ Пол. Объектно-ориентированное программирование с использованием C++: Пер. с англ. - Киев: НИИПФ ДиаСофт Лтд, 199 480с.
.Т. Фейсон. Объектно-ориентированное программирование на Borland C++ 4.5: Пер. с англ. - Киев: Диалектика, 1996. 544с.