МИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра вычислительной техники
Отчет по лабораторной работе №1
по дисциплине «Алгоритмы и структуры данных»
Студент гр. 930 |
|
Преподаватель |
Колинько П.Г. |
Тема: РАБОТА С ИЕРАРХИЕЙ ОБЪЕКТОВ: НАСЛЕДОВАНИЕ И ПОЛИМОРФИЗМ Вариант 35
Содержание
Введение ........................................................................................................ 3
Задание ........................................................................................................... 3
Постановка задачи и описание решения ..................................................... 3 Контрольные тесты ...................................................................................... 5
Вывод ............................................................................................................. 7
Текст программы ........................................................................................... 8
Цель работы
Изучение ООП, работа с иерархией объектов, наследованием и полиморфизмом
Заголовок 1
Задание
Доработать модуль shape.cpp, добавив в коллекцию ромб, который нельзя вращать и отражать по осям, разместить фигуры на место бакенбард и рогов, а также определить подходящее место в иерархии классов и написать недостающие функции-члены
Постановка задачи и описание решения
Ромб может быть любым, главное, чтобы все его стороны были равны: в программе есть два способа задания фигуры: либо через определение левого ребра, тогда фигура будет строиться относительно этого ребра, либо через определения левой вершины и задания длины ребра, исходящего из этой вершины – тогда ребро будет идти под углом в 45 градусов
Д ля инициализации фигуры “ромб” следует выбрать точки w и n (w – west, n - north), то есть через левую и верхнюю вершину, или назначить левую точку и длину ребра (итого два переопределенных конструктора). В качестве родителя для ромба был выбран класс “линия”, таким образом в классе-наследнике можно не переопределять функции перемещения и увеличения ребра. Для удобства в классе line были переименованы точки w и e в w и n, чтобы не переименовывать их в наследнике
В класс point был добавлен конструктор копирования, чтобы можно было переопределить конструктор в классе rhombus Пришлось переопределить функции определения крайних точек и функцию рисования фигуры, таким образом функции move() и resize() можно не переопределять из-за общей сигнатуры
В этом классе запрещен конструктор копирования, чтобы никто не смог скопировать этот объект: чтобы это сделать, необходимо присвоить конструктору модификатор доступа private
Для рисования бакенбард в класс myshape были добавлены левая и правая бакенбарды, таким образом они являются частью лица – они прикреплены в конструкторе
Рога же созданы в функции main и были прикреплены к козырьку шляпы с помощью функций nleft() и nright(), которые находят точки крепления и двигают к ним рога.
Контрольные тесты
Заголовок 2
Вывод
Оглавление
Цель работы 3
Изучение ООП, работа с иерархией объектов, наследованием и полиморфизмом 3
Заголовок 1 3
Задание 3
Доработать модуль shape.cpp, добавив в коллекцию ромб, который нельзя вращать и отражать по осям, разместить фигуры на место бакенбард и рогов, а также определить подходящее место в иерархии классов и написать недостающие функции-члены 3
Постановка задачи и описание решения 3
Ромб может быть любым, главное, чтобы все его стороны были равны: в программе есть два способа задания фигуры: либо через определение левого ребра, тогда фигура будет строиться относительно этого ребра, либо через определения левой вершины и задания длины ребра, исходящего из этой вершины – тогда ребро будет идти под углом в 45 градусов 3
Для инициализации фигуры “ромб” следует выбрать точки w и n (w – west, n - north), то есть через левую и верхнюю вершину, или назначить левую точку и длину ребра (итого два переопределенных конструктора). В качестве родителя для ромба был выбран класс “линия”, таким образом в классе-наследнике можно не переопределять функции перемещения и увеличения ребра. Для удобства в классе line были переименованы точки w и e в w и n, чтобы не переименовывать их в наследнике 3
Контрольные тесты 5
Заголовок 2 5
Вывод 8
//Были добавлены только те модули, которые были изменены или добавлены 12
//shape.h 12
class rhombus : public line{ 12
rhombus(const rhombus& a); 12
public: 12
rhombus(point a, point b): line(a, b) {} 12
rhombus(point a, int L): line(a, L) {w = point(a); n = point(a.x+L, a.y+L); } 12
point south( ) const { return point(w.x > n.x? w.x: n.x, 2*(w.y>n.y? n.y: w.y) - (w.y>n.y? w.y: n.y) ); } 12
point east( ) const { return point(2*(w.x>n.x? w.x: n.x) - (w.x>n.x? n.x: w.x), w.y>n.y? n.y: w.y); } 12
point neast( ) const { line z(n, east()); return z.neast(); } 12
point seast( ) const { line a(south(), east()); return a.seast(); } 12
point swest( ) const { line b(w, south()); return b.swest();} 12
void draw( ) 12
{ 12
put_line(w, n); put_line(n, east( )); 12
put_line(south( ), east()); put_line(w, south( )); 12
} 12
}; 12
//shape.cpp 12
void nleft(shape &p, const shape &line) 12
{ 12
point w = line.nwest( ); 12
point down = p.south(); 12
p.move(w.x - down.x, w.y - down.y + 1); 12
} 12
void nright(shape &p, const shape &line) 12
{ 12
point w = line.neast( ), 12
down = p.south(); 12
p.move(w.x - down.x, w.y - down.y + 1); 12
} 12
class myshape : public rectangle { 13
int w, h; 13
line l_eye, r_eye; 13
line mouth; // рот 13
rhombus l_buck ,r_buck; 13
public: 13
myshape(point, point); 13
void draw( ); 13
void move(int, int); 13
void resize(int) { } 13
}; 13
myshape :: myshape(point a, point b) 13
: rectangle(a, b), 13
w(neast( ).x - swest( ).x + 1), 13
h(neast( ).y - swest( ).y + 1), 13
l_eye(point(swest( ).x + 2, swest( ).y + h * 3 / 4), 2), 13
r_eye(point(swest( ).x + w - 4, swest( ).y + h * 3 / 4), 2), 13
mouth(point(swest( ).x + 2, swest( ).y + h / 4), w - 4), 13
l_buck(point(a.x-3, a.y+1), point(a.x-2, a.y+2)), 13
r_buck(point(b.x+1, a.y+1), point(b.x+2, a.y+2)) 13
{ } … 13
//main.cpp 13
#include "shape.cpp" 13
int main() 13
{ 13
setlocale(LC_ALL, "Rus"); 13
screen_init( ); 13
13
//== 1.Объявление набора фигур == 13
rectangle hat(point(0, 0), point(14, 5)); 13
line brim(point(0,15),17); 13
myshape face(point(15,10), point(27,18)); 13
h_circle beard(point(40,10), point(50,20)); 13
rhombus l_horn(point(3, 3), 3), 13
r_horn(point(9, 3), point(12, 6)); 14
shape_refresh( );//вывод на экран 14
cout << "=== Generated... ===\n"; 14
system("pause>0"); //Смотреть исходный набор 14
//== 2.Подготовка к сборке == 14
hat.rotate_right( ); 14
brim.resize(2); 14
face.resize(2); 14
beard.flip_vertically(); 14
shape_refresh( ); 14
cout << "=== Prepared... ===\n"; 14
system("pause>0"); //Смотреть результат поворотов/отражений 14
//== 3.Сборка изображения == 14
// face.move(0, -10); // Лицо - в исходное положение 14
up(brim, face); 14
up(hat, brim); 14
nleft(l_horn, brim); 14
nright(r_horn, brim); 14
down(beard, face); 14
shape_refresh( ); 14
cout << "=== Ready! ===\n"; 14
system("pause>0"); 14
return 0; 14
} 14
Таким образом, были изучены такие концепции ООП, как наследование и полиморфизм: наследование необходимо для построения иерархии классов и для избегания повторного написание кода. Полиморфизм нужен для обработки разных типов данных одним и тем же кодом.
Текст программы
//Были добавлены только те модули, которые были изменены или добавлены
//shape.h
class rhombus : public line{
rhombus(const rhombus& a);
public:
rhombus(point a, point b): line(a, b) {}
rhombus(point a, int L): line(a, L) {w = point(a); n = point(a.x+L, a.y+L); }
point south( ) const { return point(w.x > n.x? w.x: n.x, 2*(w.y>n.y? n.y: w.y) - (w.y>n.y? w.y: n.y) ); }
point east( ) const { return point(2*(w.x>n.x? w.x: n.x) - (w.x>n.x? n.x: w.x), w.y>n.y? n.y: w.y); }
point neast( ) const { line z(n, east()); return z.neast(); }
point seast( ) const { line a(south(), east()); return a.seast(); }
point swest( ) const { line b(w, south()); return b.swest();}
void draw( )
{
put_line(w, n); put_line(n, east( ));
put_line(south( ), east()); put_line(w, south( ));
}
};
//shape.cpp
void nleft(shape &p, const shape &line)
{
point w = line.nwest( );
point down = p.south();
p.move(w.x - down.x, w.y - down.y + 1);
}
void nright(shape &p, const shape &line)
{
point w = line.neast( ),
down = p.south();
p.move(w.x - down.x, w.y - down.y + 1);
}
class myshape : public rectangle {
int w, h;
line l_eye, r_eye;
line mouth; // рот
rhombus l_buck ,r_buck;
public:
myshape(point, point);
void draw( );
void move(int, int);
void resize(int) { }
};
myshape :: myshape(point a, point b)
: rectangle(a, b),
w(neast( ).x - swest( ).x + 1),
h(neast( ).y - swest( ).y + 1),
l_eye(point(swest( ).x + 2, swest( ).y + h * 3 / 4), 2),
r_eye(point(swest( ).x + w - 4, swest( ).y + h * 3 / 4), 2),
mouth(point(swest( ).x + 2, swest( ).y + h / 4), w - 4),
l_buck(point(a.x-3, a.y+1), point(a.x-2, a.y+2)),
r_buck(point(b.x+1, a.y+1), point(b.x+2, a.y+2))
{ } …
//main.cpp
#include "shape.cpp"
int main()
{
setlocale(LC_ALL, "Rus");
screen_init( );
//== 1.Объявление набора фигур ==
rectangle hat(point(0, 0), point(14, 5));
line brim(point(0,15),17);
myshape face(point(15,10), point(27,18));
h_circle beard(point(40,10), point(50,20));
rhombus l_horn(point(3, 3), 3),
r_horn(point(9, 3), point(12, 6));
shape_refresh( );//вывод на экран
cout << "=== Generated... ===\n";
system("pause>0"); //Смотреть исходный набор
//== 2.Подготовка к сборке ==
hat.rotate_right( );
brim.resize(2);
face.resize(2);
beard.flip_vertically();
shape_refresh( );
cout << "=== Prepared... ===\n";
system("pause>0"); //Смотреть результат поворотов/отражений
//== 3.Сборка изображения ==
// face.move(0, -10); // Лицо - в исходное положение
up(brim, face);
up(hat, brim);
nleft(l_horn, brim);
nright(r_horn, brim);
down(beard, face);
shape_refresh( );
cout << "=== Ready! ===\n";
system("pause>0");
return 0;
}
Санкт-Петербург
2020