Объектно-ориентированное программирование - Учебное пособие (А.А. Хусаинов)

5.2. организация списка объектов различного типа

 

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

Класс точки зададим как класс элемента списка, имеющего помимо координат указатель на следующий элемент, конструктор и виртуальную функцию вывода на экран содержимого объекта класса точки:

 

// Класс точки

class Point

   {

               // Собственные элементы

               friend MPoint;            // Класс MPoint будет дружественным

   protected:

               // Защищённые элементы

               int x,y;                         // Координаты

               int itype;                      // Тип

               Point *next;   // Указатель на следующий элемент в списке

   public:

               // Общедоступные элементы

               Point(int a,int b):x(a), y(b), itype(0) {}           // Конструктор

 

               virtual void get()

                           {

                           // Вывод координат точки

                           cout << "Point(" << x << ',' << y << ") ";

                           }

 

               virtual int type()          // Виртуальная функция возвращения типа

                           {

                           return itype;

                           }

   };

 

Класс отрезка определим как производный от класса точки, к которому добавлены координаты конца отрезка и переопределена функция вывода на экран:

 

// Класс линии (производный от класса точки)

class Line: public Point

   {

               // Собственные элементы

               friend MPoint;            // Класс MPoint будет дружественным

               int x2,y2;                     // Координаты второго конца линии

               Point *next;     // Указатель на следующий элемент в списке

   public:

               // Общедоступные элементы

 

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

               Line(int a,int b,int a2,int b2):Point(a,b), x2(a2), y2(b2) {}

 

               virtual void get()

                           {

                           // Вывод координат линии

                           cout << "Line(" << x << ',' << y << ")(";

                           cout << x2 << ',' << y2 << ") ";

                           }

   } ;

 

Определим класс списка, состоящий из указателя на первый элемент и функций добавления точки, добавления отрезка и вывода элементов списка на экран:

 

// Класс списка

class MPoint

   {

               // Собственные элементы

               Point *p;                      // Указатель на голову списка

   public:

               // Общедоступные элементы

               MPoint() { p = NULL; }                    // Конструктор

 

               void insert(Point z);    // Добавление точки в список

               void insert(Line t);                  // Добавление линии в список

               void display();                         // Вывод содержимого списка

   };

 

Для того чтобы сделать доступными поля классов Point и Line, объявим класс Mpoint дружественным для этих классов. После добавления тестирующей главной программы получим окончательный текст программы.

 

#include <conio.h>

#include <iostream.h>

 

class MPoint;

 

// Класс точки

class Point

   {

               // Собственные элементы

               friend MPoint;            // Класс MPoint будет дружественным

   protected:

               // Защищённые элементы

               int x,y;                         // Координаты

               int itype;                      // Тип

               Point *next;   // Указатель на следующий элемент в списке

   public:

               // Общедоступные элементы

               Point(int a,int b):x(a), y(b), itype(0) {}           // Конструктор

 

               virtual void get()

                           {

                           // Вывод координат точки

                           cout << "Point(" << x << ',' << y << ") ";

                           }

 

               virtual int type()          // Виртуальная функция возвращения типа

                           {

                           return itype;

                           }

   };

 

// Класс линии (производный от класса точки)

class Line: public Point

   {

               // Собственные элементы

               friend MPoint;            // Класс MPoint будет дружественным

               int x2,y2;                     // Координаты второго конца линии

               Point *next;     // Указатель на следующий элемент в списке

   public:

               // Общедоступные элементы

 

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

               Line(int a,int b,int a2,int b2):Point(a,b), x2(a2), y2(b2) {}

 

               virtual void get()

                           {

                           // Вывод координат линии

                           cout << "Line(" << x << ',' << y << ")(";

                           cout << x2 << ',' << y2 << ") ";

                           }

   } ;

// Класс списка

class MPoint

   {

               // Собственные элементы

               Point *p;                      // Указатель на голову списка

   public:

               // Общедоступные элементы

               MPoint() { p = NULL; }                    // Конструктор

 

               void insert(Point z);    // Добавление точки в список

               void insert(Line t);                  // Добавление линии в список

               void display();                         // Вывод содержимого списка

   };

 

// Вывод содержимого списка

void MPoint::display()

   {

   Point *q = p;   // Создаём указатель и устанавливаем его

                                       // на голову списка

   while(q)           // Пока не дойдём до конца списка

               {

               q->get();          // Вывод элемента списка

               q=q->next;      // Переход к следующему элементу

               }

   }

 

// Добавление точки в список

void MPoint::insert(Point z)

   {

   if(!p) // Если список пустой

               {

               p = new Point(z.x, z.y);           // Создаём новый элемент

               p->next = NULL;                               // Следующего элемента пока нет

               return;                                      // Выход из функции

               }

 

   // Если список не пустой

   Point *q = p;   // Создаём указатель и устанавливаем его

                                       // на голову списка

   // Идём до конца списка

   while(q->next)

               q = q->next;    // Переход к следующему элементу списка

 

   q->next = new Point(z.x,z.y);             // Создаём новый элемент

   q->next->next = NULL;                                 // Следующего элемента пока нет

   }

 

// Добавление линии в список

void MPoint::insert(Line z)

   {

   // Если список пустой

   if(!p)

               {

               p = new Line(z.x,z.y,z.x2,z.y2);         // Создаём новый элемент

               p->next = NULL;                               // Следующего элемента пока нет

               return;                                      // Выход из функции

               }

 

   // Если список не пустой

   Point *q = p;   // Создаём указатель и устанавливаем его

                                       // на голову списка

   // Идём до конца списка

   while(q->next)

               q = q->next;    // Переход к следующему элементу списка

 

   q->next = new Line(z.x,z.y,z.x2,z.y2);           // Создаём новый элемент

   q->next->next = NULL;                                 // Следующего элемента пока нет

   }

void main()

   {

   clrscr();            // Очистка экрана

 

   MPoint a;        // Создаём список

   Line l1(10,100,-1,0);   // Создаём линию

   Point p1(1,2);              // Создаём точку

 

   a.insert(l1);                  // Добавляем в список линию

   a.insert(l1);                  // Добавляем в список линию

   a.insert(p1);                 // Добавляем в список точку

   a.insert(p1);                 // Добавляем в список точку

   a.insert(l1);                  // Добавляем в список линию

   a.insert(p1);                 // Добавляем в список точку

 

   a.display();                  // Выводим содержимое списка на экран

 

   getch();                        // Ожидание нажатия клавиши

   }

 

В результате работы программы на экран будут выведены строки:

 

   Line(10,100)(-1,0)

   Line(10,100)(-1,0)

   Point(1,2)

   Point(1,2)

   Line(10,100)(-1,0)

   Point(1,2)