Лекции.Орг


Поиск:




Разнородные связанные списки




 

Как и в разнородных массивах, каждый объект в разнородном списке образован от общего для всех базового класса. Каждая базовая составляющая объекта содержит указатель на следующий объект в списке. Благодаря полиморфизму указатель используется для выполнения методов производного объекта, невзирая на его тип.

Проиллюстрируем эти понятия на связанном списке геометрических объектов, образованных от варианта класса Shape.

Сертификация класса NodeShape

 

объявление

#include “graphlib.h”

 

class NodeShape

{

protected:

//координаты базовой точки, образец заполнения

//и указатель на следующий узел

float x, y;

int fillpat;

NodeShape *next;

 

public:

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

NodeShape (float h=0, float v=0, int fill=0);

 

//виртуальная функция рисования

virtual void Draw (void) const;

 

//методы обработки списков

void InsertAfter (NodeShape *p);

NodeShape *DeleteAfter (void);

NodeShape *Nexn (void);

};

описание

 

Координаты (x,y) задают базовую точку для производного объекта, который должен быть нарисован и заштрихован по образцу fillpat. Метод Draw инициализирует образец заполнения и графической системе и указатель next, указывающий на следующий объект типа NodeShape в связанном списке. Методы InsertAfter и DeleteAfter поддерживают кольцевой список посредством включения или удаления узла, следующего за текущим. Метод Next возвращает указатель на следующий узел.

Класс NodeShape находится в файле shapelst.h

 

Реализация класса NodeShape

Реализация класса NodeShape сделана по образцу класса CNode. Так как предполагается кольцевой список, конструктор должен создать начальный узел, который указывает на самого себя.

 

 
 

 

 

 


 

//конструктор. задаёт начальное значение базовой точки,

//образца заполнения и указателя next

NodeShape::NodeShape (float h, float v, int fill):

x (h), y (v), fillpat (fill)

{

next = this;

}

 

Образование связанных геометрических классов. Геометрические классы CircleFigure и RectangleFigure являются производными от класса NodeShape. В дополнение к методам базового класса они содержат метод Draw, перекрывающий виртуальный метод Draw базового класса. Методы Area и Perimeter не включаются. Мы используем класс CircleFigure для иллюстрации понятий.

 

//класс CircleFigure, образованный от класса NodeShape

class CircleFigure: public NodeShape

{

protected:

//радиус окружности

float radius;

 

public:

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

CircleFigure (float h, float v, float r, int fill);

 

//виртуальная функция рисования окружности

virtual void Draw (void) const;

};

 

//конструктор. инициализирует базовый класс и радиус

CircleFigure:: CircleFigure (float h, float v, float r, int fill):

NodeShape (h, v, fill), radius (r)

{}

 

//задать образец заполнения посредством вызова базового

//метода Draw и нарисовать окружность

void CircleFigure::Draw (void) const

{

NodeShape::Draw();

DrawCircle (x, y, radius);

}

 

Мы также включили в файл shapelst.h новый геометрический класс RightTriangle, который описывает прямоугольный треугольник с помощью координат самой левой точки его гипотенузы, базы и высоты.

 

 
 


y

 

 
 


(x, y) высота

 

x база

 

 

Чтобы сформировать связанный список, объявим заголовок, имеющий тип NodeShape и имя listHeader. Начиная с этого заголовка, будем динамически создавать узлы и с помощью InsertAfter включать их в список последовательно друг за другом. Например, следующая итерация создаёт четырёхэлементный список, в котором чередуются объекты-окружности и объекты-треугольники:

 

 

listHeader

 


//заголовок списка и указатель для создания нового списка

NodeShape listHeader, *p;

float x, y, radius, height;

 

//установить р на начала списка

p = &listHeader;

 

//включить 4 узла в список

for (int i=0; i<4; i++)

{

//координаты базовой точки

cout << “Введите x и y:”;

cin >> x >> y;

if (i % 2 == 0) //если 1 чётное, добавить окружность

{

 

cout << “Введите радиус окружности: ”;

cin >> radius;

//включить объект с заполнением в i список

p -> InsertAfter (new Circle (x, y, radius, i));

}

else //если i нечётное, добавить прямоугольный треугольник

{

cout << “Введите базу и высоту для прямоугольного

треугольника: ”;

cin >> base >> height;

p -> InsertAfter (new RightTriangle (x, y, radius, i));

}

//передвинуть р на только что созданный узел

p = p -> Next();

}

Динамическое связывание имеет принципиальное значение во время прохождения списка и визуального отображения содержащихся в нём объектов. В приведённом ниже фрагменте кода указатель р указывает либо на объект типа Circle, либо на объект типа RightTriangle. Поскольку Draw является виртуальной функцией, выполняется метод Draw того или иного производного класса.

 

p = listHeader.Next();

while (p!= &listHeader)

{

p -> Draw();

p = p->Next();

}

 

Теперь мы готовы поставить задачу создания и управления разнородными списками целиком.

 





Поделиться с друзьями:


Дата добавления: 2015-09-20; Мы поможем в написании ваших работ!; просмотров: 295 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Велико ли, мало ли дело, его надо делать. © Неизвестно
==> читать все изречения...

998 - | 762 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.008 с.