7. Определите класс
Striped_closed_polyline
, используя приемы из класса
Striped_rectangle
(для этого придется потрудиться).
8. Определите класс
Octagon
, реализующий правильный восьмиугольник. Напишите тестовую программу, выполняющую все его функции-члены (определенные вами или унаследованные от класса
Shape
).
9. Определите класс
Group
, служащий контейнером объектов класса
Shape
с удобными операциями над членами класса
Group
. Подсказка:
Vector_ref
. Используя класс
Group
, определите класс, рисующий шахматную доску, по которой шашки могут перемещаться под управлением программы.
10. Определите класс
Pseudo_window
, напоминающий класс
Window
. Постарайтесь не прилагать героических усилий. Он должен рисовать закругленные углы, метки и управляющие пиктограммы. Возможно, вы сможете добавить какое-нибудь фиктивное содержание, например изображение. На самом деле с этим изображением ничего не надо делать. Допускается (и даже рекомендуется), чтобы оно появилось в объекте класса
Simple_window
.
11. Определите класс
Binary_tree
, производный от класса
Shape
. Введите параметр, задающий количество уровней (
levels==0
означает, что в дереве нет ни одного узла,
levels==1
означает, что в дереве есть один узел,
levels==2
означает, что дерево состоит из вершины и двух узлов,
levels==3
означает, что дерево состоит из вершины и двух дочерних узлов, которые в свою очередь имеют по два дочерних узла, и т.д.). Пусть узел изображается маленьким кружочком. Соедините узлы линиями (как это принято). P.S. В компьютерных науках деревья изображаются растущими вниз от вершины (забавно, но нелогично, что ее часто называют корнем).
12. Модифицируйте класс
Binary_tree
так, чтобы он рисовал свои узлы с помощью виртуальной функции. Затем выведите из класса
Binary_tree
новый класс, в котором эта виртуальная функция замещается так, что узлы изображаются иначе (например, в виде треугольников).
13. Модифицируйте класс
Binary_tree
так, чтобы он имел параметр (или параметры, указывающие, какой вид линии используется для соединения узлов (например, стрелка, направленная вниз, или красная стрелка, направленная вверх). Заметьте, как в этом и последнем упражнениях используются два альтернативных способа, позволяющих сделать иерархию классов более гибкой и полезной.
14. Добавьте в класс
Binary_tree
операцию, добавляющую к узлу текст. Для того чтобы сделать это элегантно, можете модифицировать проект класса
Binary_tree
. Выберите способ идентификации узла; например, для перехода налево, направо, направо, налево и направо вниз по бинарному дереву можете использовать строку "
lrrlr
" (корневой узел может соответствовать как переходу влево, так и вправо).
15. Большинство иерархий классов не связано с графикой. Определите класс
Iterator
, содержащий чисто виртуальную функцию
next()
, возвращающую указатель типа
double*
(см. главу 17). Теперь выведите из класса
Iterator
классы
Vector_iterator
и
List_iterator
так, чтобы функция
next()
для класса
Vector_iterator
возвращала указатель на следующий элемент вектора типа
vector<double>
, а для класса
List_iterator
делала то же самое для списка типа
list<double>
. Инициализируйте объект класса
Vector_iterator
вектором
vector<double>
и сначала вызовите функцию
next()
, возвращающую указатель на первый элемент, если он существует. Если такого элемента нет, верните нуль. Проверьте этот класс с помощью функции
void print(Iterator&)
, выводящей на печать элементы вектора типа
vector<double>
и списка типа
list<double>
.
16. Определите класс
Controller
, содержащий четыре виртуальные функции:
on()
,
off()
,
set_level(int)
и
show()
. Выведите из класса
Controller
как минимум два класса. Один из них должен быть простым тестовым классом, в котором функция
show()
выводит на печать информацию, включен или выключен контроллер, а также текущий уровень. Второй производный класс должен управлять цветом объекта класса
Shape
; точный смысл понятия “уровень” определите сами. Попробуйте найти третий объект для управления с помощью класса
Controller
.
17. Исключения, определенные в стандартной библиотеке языка C++, такие как
exception
,
runtime_error
и
out_of_range
(см. раздел 5.6.3), организованы в виде иерархии классов (с полезной виртуальной функцией
what()
, возвращающей строку, которая предположительно содержит объяснение ошибки). Найдите источники информации об иерархии стандартных исключений в языке C++ и нарисуйте диаграмму этой иерархии классов.
Послесловие
Идеалом программирования вовсе не является создание одной программы, которая делает все. Цель программирования — создание множества классов, точно отражающих понятия, работающих вместе и позволяющих нам элегантно создавать приложения, затрачивая минимум усилий (по сравнению со сложностью задачи) при адекватной производительности и уверенности в правильности результатов. Такие программы понятны и удобны в сопровождении, т.е. их коды можно просто объединить, чтобы как можно быстрее выполнить поставленное задание. Классы, инкапсуляция (поддерживаемая разделами
private
и
protected
), наследование (поддерживаемое механизмом вывода классов), а также динамический полиморфизм (поддерживаемый виртуальными функциями) являются одними из наиболее мощных средств структурирования систем.
Глава 15
Графические функции и данные
“Лучшее — враг хорошего”.
Вольтер (Voltaire)
В любой области приложений, связанной с эмпирическими данными или моделированием процессов, необходимо строить графики. В этой главе обсуждаются основные механизмы построения таких графиков. Как обычно, мы продемонстрируем использование таких механизмов и рассмотрим их устройство. В качестве основного примера используется построение графика функции, зависящей от одного аргумента, и отображение на экране данных, записанных в файле.