МИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра вычислительной техники
Отчет по лабораторной работе №2
по дисциплине «Алгоритмы и структуры данных»
Студент гр. 930 |
|
Преподаватель |
Колинько П.Г. |
Тема: Поддержка обработки исключительных ситуаций Вариант 35
Содержание
Введение ........................................................................................................ 3
Задание ........................................................................................................... 3
Постановка задачи и описание решения ..................................................... 3 Контрольные тесты ...................................................................................... 4
Вывод ............................................................................................................. 6
Текст программы ........................................................................................... 7
Цель работы
Изучение механизма обработки исключительных ситуаций
Задание
Переработать программу работы с библиотекой фигур, дополнив ее механизмом контроля исключительных ситуаций.
Постановка задачи и описание решения
В программе были созданы и перехвачены два исключения: первое находится в line::move(), перехвачено в main, второе создано в rhombus::draw(), перехвачено в shape_refresh().
В первом методе с помощью throw бросается объект типа исключения, а во втором – целое число, чтобы показать вариативность обработки исключений: в таком случае в блоке catch необходимо указать тип int.
Пришлось перегрузить метод on_screen(point& a), чтобы было проще совершать проверку
Класс line является родителем класса rhombus, поэтому метод move() применим и к нему. Исключение вызывается так: если фигура была перемещена за экран, то есть координата одной из точек меньше 0 или больше максимума, кидается объект типа invalid_argument, и координаты точек остаются теми же, что и до вызова, то есть фигура осталась на месте
Метод rhombus::draw() кидает исключение, если при рисовании одна из точек ромба окажется не на экране: если это так, то ромб распечатается не полностью, и лучше бы он вообще не печатался. Так как метод move() не позволяет перемещать фигуру за экран, то единственный способ вызвать исключение - задать в конструкторе координаты точек, выходящих за экран. Так как неизвестно, куда распечатывать фигуру, то было принято решение не печатать ее вообще: это сделано путем удаления фигуры из листа shape::shapes, чтобы фигура не выводилась после shape_refresh()
Контрольные тесты
Тесты без исключений были показаны в предыдущей лабораторной работе, в этой стоит показать только исключительные случаи
Перемещение ромба за экран
try{ l_horn.move(-5, 5); }…
Высветилось исключение о недопустимости перемещения
Рисование ромба, находящийся за экраном
Например, пользователь неверно задал начальные координаты ромба: из-за этого он не будет выводиться на консоль rhombus l_horn(point(-3, 3), 3) Как следствие
Фигура не будет выводиться до конца выполнения программы, так как она удалена из листа shapes
Вывод
Таким образом, был изучен механизм обработки исключительных ситуаций, с помощью которого стало проще находить и исправлять ошибки
Текст программы
//Были добавлены только те модули, которые были изменены или добавлены в первой лабораторной
//shape.h
void shape_refresh( )
{
screen_clear( );
for (auto p : shape :: shapes)
{
try{ p->draw( ); }
catch(int i)
{
cout << "Error N " << i << ": figure doesn't fit on screen!\n";
cout << "I won't display this!!!\n";
shape::shapes.remove(p);
}
}
screen_refresh( );
}
class line : public shape {
/* отрезок прямой ["w", "n"].
north( ) определяет точку "выше центра отрезка и так далеко
на север, как самая его северная точка", и т. п. */
protected:
point w, n;
public:
line(point a, point b) : w(a), n(b) { };
line(point a, int L) : w(point(a.x + L - 1, a.y)), n(a) { };
point north( ) const { return point((w.x+n.x)/2, n.y<w.y? w.y : n.y); }
…
void move(int a, int b)
{
if(!on_screen(point(w.x+a, w.y+b)) || !on_screen(point(n.x+a, n.y+b)))
throw std::invalid_argument("Figure was moved beyond the screen!\n");
w.x += a;
w.y += b;
n.x += a;
n.y += b;
}…
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( )
{
if (!on_screen(west()) || !on_screen(north()) || !on_screen(east()) || !on_screen(south()))
throw 69420;
put_line(w, n); put_line(n, east( ));
put_line(south( ), east()); put_line(w, south( ));
}
};
//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();
try{ l_horn.move(10, 5); }
catch(std::invalid_argument e)
{
cout << e.what() << "I won't move it!!!\n";
}
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;
}
Санкт-Петербург
2021