Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вариант_№32.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
363.52 Кб
Скачать

Обобщенный пример наследования

Мы рассмотрели и исследовали объявленные в начале основополагающие концепции ООП – объект, класс, инкапсуляция, наследование, полиморфизм, абстракция типов. Теперь после изучения возможностей концепции наследова­ния классов (простое, множественное, управление режимами доступа, вирту­альные функции, абстрактные классы) на демонстрационных примерах полезно рассмотреть обобщающий пример.

Постановка задачи.

Рассмотрим разработку полного графического примера, в котором выво­дятся на экран монитора геометрические фигуры, с которыми можно совершать некоторые действия, например, создавать, уничтожать, перемещать по экрану и т. д. Прообразом этой задачи является пример 28.

Вместо ограниченного по своим возможностям класса Location в каче­стве базового класса опишем свойства и функции "некоторой фигуры" (Figure). Ме­стоположение ее определяется двумя координатами экрана (X, Y), инициализа­ция которых задается встроенным конструктором, а для получения значений те­кущих координат используются встроенные методы класса GetX(), GetY(). Па­раметры X, Y объявлены защищенными элементами базового класса, чтобы производные классы могли их наследовать и использовать.

В качестве основных действий, которые можно совершать с этой фигу­рой, могут быть: показ на экране (Show), удаление (Hide), перемещение (Drag). Описание этих действий представлено чистыми виртуальными функциями без их тел, что делает класс абстрактным. Для этого класса нельзя создать реаль­ный объект на экране, но можно определить указатель или массив указателей на базовый тип и использовать их при создании объектов производных классов. При этом могут применяться только наследуемые виртуальные функции, которые видимы через базовый указатель из производного класса.

Базовому классу наследует производный класс (Figure <- Point), который описывает простейший реальный объект "точка", координаты которой наследу­ются из базового класса (X, Y), а также задается свой параметр видимости точ­ки на экране как защищенный элемент Visible с булевыми значениями. Объяв­лены обычные методы: функция Isvisible(), определяющая видимость точки, и функция Moveto(), задающая новые координаты точки. Как невиртуальные ме­тоды они могут наследоваться производными классами. Их можно сделать вир­туальными, объявив их как virtual, и тогда в производных от Point классах необходимо замещать их "своими" виртуальными методами.

Чистые виртуальные функции класса Figure замещаются конкретными виртуальными функциями (Show(), Hide(), Drag()) в классе Point. Виртуальная функция Drag() использует обычный метод своего класса Moveto(), который определяет новые координаты объекта, а также обычную функцию общего на­значения (т.е. не метод класса) Getdelta(). Последняя определяет направление смеще­ния точки (или другой реальной фигуры) на экране по нажатию пользователем клавиш-стрелок клавиатуры (вправо, влево, вверх, вниз) и окончание процесса смещения объекта на экране при нажатии клавиши <Enter>.

В главной функции программы демонстрируется создание и перемещение точки по экрану, создание "звездного" неба с использованием стандартной функции получения случайных чисел X, Y для координат точки random(max), где max – максимальное число для координаты экрана с установленной разре­шающей способностью. Обработка программы выполняется в среде компилято­ра Borlandc 3.1.

Пример 40.

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

#include<iostream.h>

#include<conio.h>

#include<graphics.h> // для графической библиотеки

#include<stdlib.h> // для функций random(), srand(), kbhit()

#include<dos.h> // для функции delay()

const char* path= "c:\\borlandc\\bgi"; // путь к библиотеке bgi-файлов

enum Boolean { false, true }; // булевы значения

// прототип обычной функции (не метод), определенной ниже:

Boolean Getdelta (int& Deltax, int& Deltay);

class Figure // абстрактный базовый класс "фигура"

{ protected: // защищенные элементы, доступные в производных классах

int X, Y; // координаты объекта на экране

public:

Figure (int Initx, int Inity) // конструктор базового класса Figure

{ X = Initx, Y = Inity; } // инициализация координат

// встроенные функции-методы получения текущих координат объекта:

int Getx () { return X; }

int Gety () { return Y; }

// чистые виртуальные функции-методы базового класса:

virtual void Show() = 0; // изображение объекта

virtual void Hide() = 0; // стирание объекта с экрана

virtual void Drag ( int Dragby) = 0; // перемещение объекта

};

// производный класс Point с открытым доступом к базовому классу Figure:

class Point: public Figure // класс "точка"

{ protected:

Boolean Visible; // параметр видимости точки

public:

Point (int Initx, int Inity); // конструктор класса Point

// виртуальные функции-методы класса Point:

void Show(); // изображение точки на экране

void Hide(); // стирание точки с экрана

void Drag (int Dragby); // перемещение точки по экрану

// невиртуальные методы класса Point:

Boolean Isvisible() { return Visible;} // проверка точки на видимость

void Moveto (int Newx, int Newy); // смещение точки на новое место

};

// методы класса Point:

Point:: Point (int Initx, int Inity): // конструктор класса Point

Figure (Initx, Inity) // передача аргументов базовому классу

{ Visible = false; // инициализация параметра Point

}

void Point:: Show() // метод изображения точки на экране

{ if ( ! Visible) // если точка невидима, то

{ Visible = true; // установка видимости точки

putpixel (X, Y, getcolor() ); // изображение цветной точки

}

}

void Point:: Hide() // метод стирания точки с экрана

{ if (Visible) // если точка видима, то

{ Visible = false; // установка невидимости точки

putpixel (X, Y, getbkcolor() ); // закрашивание точки цветом фона

}

}

void Point:: Moveto (int Newx, int Newy) // метод смещения точки

{ if (Visible) Hide (); // стирание точки

X = Newx; // новые координаты точки X и Y

Y = Newy;

Show (); // изображение точки

}

void Point:: Drag( int Dragby) // метод смещения фигуры на величину Dragby

{ int Deltax, Deltay; // смещение по X, Y

int Figurex, Figurey; // координаты по X, Y

Show(); // изображение точки

while ( Getdelta ( Deltax, Deltay) ) // цикл перемещения точки:

{ Figurex = Getx()+( Deltax * Dragby ); // смещение по X

Figurey = Gety()+( Deltay * Dragby ); // смещение по Y

Moveto ( Figurex, Figurey); // перемещение точки на новое место

}

}

/* обычная функция (вне классов) определения направления смещения объекта,

которая анализирует код нажатой управляющей клавиши и возвращает

разрешение на смещение (true) в заданном направлении через параметры

ссылки (&), либо отмену смещения (false) при нажатии клавиши <Enter>;

используется в методе Point:: Drag():

*/

Boolean Getdelta (int& Deltax, int& Deltay) // & - ссылки на смещение

{ char Keychar; // переменная символа клавиши

Boolean Quit; // переменная смещения

Deltax = 0; // начальные значения смещений

Deltay = 0;

do { Keychar = getch (); // цикл анализа кода нажатой клавиши:

if ( Keychar == 13) // если код = 13 (<Enter>), то

return ( false); // конец смещения объекта;

if (Keychar == 0) //если код = 0, то это скэн-код клавиши

{ Quit = true; // подтверждение смещения

Keychar = getch (); // чтение 2- го байта кода

switch ( Keychar) // анализ кода управления:

{ case 72: Deltay = -1; break; // стрелка вниз

case 80: Deltay = 1; break; // стрелка вверх

case 75: Deltax = -1; break; // стрелка влево

case 77: Deltax = 1; break; // стрелка вправо

default : Quit = false; // неправильная клавиша

}

}

} while ( ! Quit); // продолжение цикла чтения кода клавиш

return ( true); // разрешение смещения объекта

}

void main() // главная функция:

{ int graphdriver = DETECT, graphmode; // данные режима графики

initgraph (&graphdriver, &graphmode, path); // инициализация графики

int n, i, x, y, maxx, maxy, maxcolor, seed, color; // рабочие переменные

int DelayTime; // временная задержка

x=100; // координаты экрана (х,у)

y=200;

Point Apoint ( x, y); // создание и инициализация точки

Apoint.Show(); // изображение точки

Apoint.Drag(20); // перемещение точки по экрану

getch (); // задержка образа экрана

/*

// изображение статического "звездного неба":

cout<< "Enter number of points (<32000): ";

cin >> n; // ввод количества точек

for (i=0; i<n; i++) // цикл создания точек

{ x = random(639); // случайные коодинаты точки (х, у)

y = random(479);

Point Apoint (x,y); // создание и инициализация точки

Apoint.Show(); // изображение точки

}

*/

/*

// изображение мерцающих цветных точек

maxx = getmaxx(); // количество пикселей по оси Х экрана

maxy = getmaxy(); // количество пикселей по оси Y экрана

maxcolor = getmaxcolor(); // количество цветов

cout<< "Enter number of points (<2000): ";

cin >> n; // ввод количества точек

cout<<"Enter DelayTime (millisecond) = ";

cin >> DelayTime; // ввод временной задержки

while ( ! kbhit() ) // цикл пока не нажата любая клавиша

{ seed = random (RAND_MAX); // начальное случайное число

srand (seed); // запуск генератора случайных чисел

for (i=0; i<n; i++) // цикл создания точек

{ x = random(maxx); // случайные координаты по x

y = random(maxy); // и по y

color = random(maxcolor); // случайное значение цвета

setcolor(color); // установка цвета

Point Apoint ( x, y); // создание и инициализация точки

Apoint.Show(); // изображение точки

}

delay (DelayTime); // задержка по времени

srand ( seed); // запуск генератора случайных чисел

for (i=0; i<n; i++) // цикл создания точек

{ x = random (maxx); // случайные коодинаты точки (х, у)

y = random (maxy);

color = random (maxcolor); // случайное значение цвета

if ( color == getpixel (x, y)) // если цвет точки = случайному, то

{ Apoint.Moveto (x, y); // смещение точки и

Apoint.Hide(); // стирание

}

}

}

getch (); // задержка экрана

closegraph(); // закрытие графического режима

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]