Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Классы List, Iterator.DOC
Скачиваний:
5
Добавлен:
05.11.2018
Размер:
167.94 Кб
Скачать

Абстрактный базовый класс List

Абстрактный класс служит шаблоном для своих производных классов. Он может содержать данные и методы, совместно используемые всеми производными классами. С помощью чистых виртуальных функций он обеспечивает, объявления общедоступных методов, которые должны быть реализованы производными классами. В качестве примера мы разрабатываем абстрактный класс List как шаблон для списковых коллекций. Этот класс имеет переменную (член класса) size, используемую для определения методов ListSize и ListEmpty. Эти функции доступны каждому производному классу, обеспечивающему корректное сохранение size при включении или удалении элементов, а также при очистке списка. Несмотря на то, что методы ListSize и ListEmptg представляются в базовом классе, они могут быть либо подменены в производном классе, либо восприняты по умолчанию. Остальные методы объявляются как чистые виртуальные функции базового класса и должны подменяться в производном классе. Функция Insert зависит от конкретного класса коллекций. В одном образовании Insert может помещать данные в последовательный список, а для бинарного дерева или словаря требуется совершенно иной алгоритм включения.

Спецификация класса List

template <class T>

class List

{

protected:

// число элементов списка, обновляемое производным классом

int size;

public:

// конструктор

List(void);

// методы доступа к списку

virtual int Listsize(void) const;

virtual int ListEmpty(void) const;

virtual int Find (T& item) = 0;

// методы модификации списка

virtual void Insert (const T& item) = 0;

virtual void Delete (const T& item) = 0;

virtual void ClearList (void) = 0;

};

Реализация методов класса List

В любом производном классе методы модификации списка должны поддерживать size — член базового класса. Начальное значение 0 присваивается этой переменной конструктором класса List.

// конструктор устанавливает Size в 0

template <class T>

int List<T>::List(void): size(0)

{}

Методы ListSize и ListEmpty класса List зависят только от значения size.

Они реализуются в базовом классе и затем используются любым производным

классом.

// возвратить размер списка

template <class T>

ist List<T>::List(void) const

{

return size;

}

// проверить, пуст ли список

template <class T>

ist List<T>::ListEmpty(void) const

}

return size = =0;

}

Образование класса SeqList из абстрактного базового класса List

Первый раз мы представили класс SeqList в гл. 1, и в последующих главах

показали реализацию массива и связанного списка. Теперь мы снова рассмотрим SeqList в качестве класса, образованного от абстрактного класса List. Методы DeleteFront и GetData отсутствуют в абстрактном классе, так как они применимы только к последовательному списку.

Спецификация класса SeqList

объявление

template <с1ass T>

class SeqList: public List

{

protected:

// связанный список, доступный производным классам

LinkedList<T> llist;

public:

// конструктор

SeqList(void);

// методы доступа к списку

virtual int Find (T& item);

Т GetData(int pos);

// методы модификации списка

virtual void Insert (const Т& item);

virtual void Delete (const Т& item);

Т DeleteFront(void);

virtual void ClearList (void);

// для объекта типа SeqListIterator требуется доступ к llist

friend class SeqListIterator<T>;

}

описание

Являясь наследником абстрактного класса List, класс SeqList должен поддерживать указанные в List операции. Поскольку SeqList реализует последовательный список, в этот производный класс должны быть добавлены метод, GetData, принимающий позицию элемента в качестве параметра, и метод DeleteFront, удаляющий первый элемент списка.

Методы Insert, Delete и ClearList поддерживают защищенный элемент данных базового класса size, поэтому методы ListSize и ListEmpty подменять не нужно.

Прохождение объекта типа SeqList можно выполнить с помощью средства,

называемого итератором (iterator). Этот инструмент, объявляемый как объект

типа SeqListIterator, должен иметь доступ к llist, что обеспечивается объявлением класса SeqListIterator дружественным. Итераторы обсуждаются в следующем разделе. Производная версия класса SeqList включена в файл seqlist2.h.

Реализация производной версии класса SeqList

Основная часть работы по реализации этого класса была сделана в гл. 9. Нам необходимо определить функции Insert, Delete, ClearList и Find. повторяем их определения, сделанные в классе LinkedList, но добавляем поддержку значения size из класса List. Например, метод Insert выглядит следующим образом:

// использовать метод InsertRear для включения элемента в хвост списка

template <class T>

void SeqList<T>::Insert(const T& item)

{

llist.InsertRear(item);

size++; // обновить size в классе List

}

Конструктор производного класса SeqList вызывает конструктор класса List, который обнуляет size.

//конструктор умолчания

//инициализация базового класса

template <class Т>

SeqList<T>::SeqL1st(void): List<T>( )

{}