Пример 5.6.3.1. Реализация шаблонного связного списка
//-------------------------------------------------------------------------------------------
// описание интерфейса шаблонного класса связного списка TList
template<class T> class TList
{
public:
void Add(T value);
void Insert(int index, T value);
void Delete(void);
int Delete(int index);
T GetValue(int index);
int Count(void);
void CopyList(TList<T> &list);
TList();
TList(TList<T> &Object);
~TList();
TList &TList::operator =(TList<T> &list);
T &TList::operator [](int number);
private:
class ListElement;
void _deleteElement(ListElement *deletedElement);
ListElement *_getElement(int index);
ListElement *_first;
ListElement *_last;
};
//-------------------------------------------------------------------------------------------
// описание шаблонного класса элемента связного списка ListElement
template<class T> class TList<T>::ListElement
{
public:
T _value;
ListElement *_next;
ListElement *_prev;
ListElement()
{
_next = NULL;
_prev = NULL;
|
|
_value = 0;
}
ListElement(T value)
{
_next = NULL;
_prev = NULL;
_value = value;
}
};
//-------------------------------------------------------------------------------------------
// реализация метода добавления шаблонного элемента в шаблонный
// связный список класса TList
template<class T> void TList<T>::Add(T value)
{
ListElement *newElement = new ListElement(value);
if(!_first)
{
this->_first = newElement;
_last = newElement;
}
_last->_next = newElement;
newElement->_prev = _last;
newElement->_next = NULL;
_last = newElement;
_first->_prev = NULL;
};
Пример 5.6.3.2. Реализация внешних функций, обрабатывающих шаблонныйвязный список
template<class T> void PrintList(TList<T> list)
{
for(int i = 0; i < list.Count(); i++)
cout << list.GetValue(i) << " ";
cout<<endl;
}
template<class T> void InputList(TList<T> &list, int count)
{
int number;
cout<<"Введите элементы формируемого списка: "<<endl;
for (int i=0; i < count; i++)
{
cin>>number;
list.Add(number);
}
}
Пример 5.6.3.3. Реализация обработки инсключительных ситуаций
//-------------------------------------------------------------------------------------------
// в методе поиска элемента списка по заданному индексу
// обрабатывается аварийная ситуация (генерируется исключение),
|
|
// когда значение заданного индекса не соответствует границам списка
template<class T> typename TList<T>:: ListElement *TList<T>:: _getElement(int index)
{
int count = this->Count();
if (count == 0) throw "список пуст";
if ((index < 0) || (index >= count))
throw "выход за границы списка";
ListElement* element = _first;
for(int i = 1; i <= index; i++) element = element->_next;
return element;
}
//-----------------------------------------------------------------------------------------
// методы вставки, удаления, поиска значения элемента по индексу,
// а также оператор индексирования не проверяют значение индекса на
// на соответствие границам (по сравнению с реализацией связного
// списка целочисленных значений в п.5.6.1.), так как используют метод
// _getElement(int index), в котором обрабатывается данная ситуация
// и генерируется соответствующее исключение.
template<class T> T TList<T>::GetValue(int index)
{
return _getElement(index)->_value;
}
template<class T> T &TList<T>::operator [](int index)
{
return _getElement(index)->_value;
}
template<class T> void TList<T>::Delete(int index)
{
ListElement *deletedElement = _getElement(index);
_deleteElement(deletedElement);
};
template<class T> void TList<T>::Insert(int index, T value)
{
ListElement *element = _getElement(index);
ListElement *prev = element->_prev;
ListElement *next = element;
element = new ListElement(value);
element->_prev = prev;
element->_next = next;
if(prev) prev->_next= element;
else _first = element;
if(next) next-> _prev = element;
else _last = element;
}
Пример 5.6.3.4. Код, демонстрирующий способы использования класса шаблонного связного списка с обработкой исключительных ситуаций
int main()
{
setlocale(LC_ALL, "russian");
try // объявление контролируемого блока, в котором
{ // перехватываются генерируемые исключения
int ch,resp;
for(;;)
{
system("cls");
cout << endl;
cout << "\t\tГЛАВНОЕ МЕНЮ" << endl;
cout << "\t\t1 - Демонстрация работы
с шаблонными списками" << endl;
cout << "\t\t0 - Выход из программы" << endl;
cin >> ch;
switch(ch)
{
case 0:
{
cout << "\nВы уверены, что хотите
выйти? 0-Да, 1-Нет" << endl;
cin >> resp;
if (resp == 0)
return 0;
else
break;
}
case 1:
{
// объявление списка целых значений
TList<int> list1;
int number, count;
cout << "Демонстрация работы с шаб-
лонными списками." << endl;
cout << "-------------------" << endl;
cout << "Формирование списка №1" << endl;
cout << "-----" << endl;
|
|
cout << "Введите необходимое количество
элементов списка №1: ";
cin >> count;
InputList(list1, count);
cout << "---------------" << endl << endl;
cout << "Вывод списка №1" << endl;
PrintList(list1);
cout << "---------------" << endl << endl;
cout << "Вставка элемента со значением 201
на 1-ую позицию в список №1" << endl;
list1.Insert(1,201);
cout << "-----" << endl;
cout << "Вывод списка №1 " << endl;
PrintList(list1);
cout << "---------------" << endl << endl;
cout << "Удаление элемента с индексом 0
из списка №1" << endl;
list1.Delete(0);
cout << "-----" << endl;
cout << "Вывод списка №1 " << endl;
PrintList(list1);
cout << "---------------" << endl << endl;
cout << "Изменение значения элемента
с индексом 5 списка №1 " << endl;
list1[5] *= 100; //!!! внимание – исключение
cout << "-----" << endl;
|
|
cout << "Вывод списка №1 " << endl;
PrintList(list1);
cout << "---------------" << endl << endl;
// объявление вещественного списка
TList<double> tmp;
cout << "Формирование списка типа double";
cout << end << "-----" << endl;
cout << "Добавление элемента со значением
3.14 в список типа double" << endl;
tmp.Add(3.14);
cout << "Добавление элемента со значением
5.0 список типа double" << endl;
tmp.Add(5.0);
cout << "---------------" << endl << endl;
cout << "Изменение значения элемента
с индексом 1 списка типа double
на значение 2.4" << endl;
cout << "-----" << endl;
tmp[1] = 2.4;
cout << "Вывод списка типа double" << endl;
PrintList(tmp);
cout << "---------------" << endl << endl;
cout << "Вставка элемента со значением 201
на 4-ую позицию в список типа double"<<endl;
//!!! внимание - исключение
tmp.Insert(4,201);
cout << "Вывод списка типа double" << endl;
PrintList(tmp);
cout << "---------------" << endl << endl;
// объявление списка строковых значений
TList<string> str;
cout << "Формирование списка типа string";
cout << endl << "-----" << endl;
cout << "Добавление элемента со значением
'hello,' в список типа string" << endl;
str.Add("hello,");
cout << "Добавление элемента со значением
'world' список типа string" << endl;
str.Add("world");
cout << "---------------" << endl << endl;
cout << "Вывод списка типа string" << endl;
PrintList(str);
cout << "---------------" << endl << endl;
cout << "Удаление элемента с
ндексом 10 списка типа string " << endl;
//!!! внимание - исключение
str.Delete(10); //возникает ошибка
// типа const char
// в операторе индексирования
cout << "---------------" << endl << endl;
cout << "Вывод списка типа string" << endl;
PrintList(str);
cout << "---------------" << endl << endl;
system("pause");
break;
} // конец контролируемого блока try
}
}
}
catch (const char *error)
{
cout << "Возникла ошибка: "<< error << endl;
cout << "Возвращаемся в главное меню." << endl << endl;
main();
system("pause");
}
return 0;
}