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)
В любой области приложений, связанной с эмпирическими данными или моделированием процессов, необходимо строить графики. В этой главе обсуждаются основные механизмы построения таких графиков. Как обычно, мы продемонстрируем использование таких механизмов и рассмотрим их устройство. В качестве основного примера используется построение графика функции, зависящей от одного аргумента, и отображение на экране данных, записанных в файле.
15.1. Введение
15.2. Построение простых графиков
Начнем. Рассмотрим примеры того, что мы можем нарисовать и как это реализовать в программе. В частности, посмотрим на классы графического интерфейса: мы видим параболу, горизонтальную и наклонную линии.
На самом деле, поскольку эта глава посвящена графическим функциям, данная горизонтальная линия — это не просто какая-то горизонтальная линия, а график функции, представленной ниже.
double one(double) { return 1; }
Это самая простая функция, которую мы могли себе представить: она имеет один аргумент и всегда возвращает 1. Поскольку для вычисления результата этот аргумент не нужен, называть его необязательно. Для каждого значения x, переданного в качестве аргумента функции one(), получаем значение y, равное 1; иначе говоря, эта линия определяется равенством (x,y)==(x,1) при всех x.
Как любая вступительная математическая аргументация, наши рассуждения выглядят несколько тривиальными и педантичными, поэтому перейдем к более сложному примеру.
double slope(double x) { return x/2; }
Эта функция порождает наклонную линию. Для каждого аргумента x получаем значение y, равное x/2. Иначе говоря, (x,y)==(x,x/2). Эти две линии пересекаются в точке (2,1).
Теперь можем попытаться сделать кое-что интересное. Напишем квадратичную функцию, которая регулярно будет упоминаться в нашей книге.
double square(double x) { return x*x; }
Если вы помните школьную геометрию (и даже если забыли), то поймете, что эта функция определяет параболу, симметричную относительно оси (0,0), т.е. (x,y)==(x,x*x). Итак, самая нижняя точка параболы касается наклонной линии в точке (0,0).