Читаем Программирование полностью

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; }


Если вы помните школьную геометрию (и даже если забыли), то поймете, что эта функция определяет параболу, симметричную относительно оси y, а ее самая нижняя точка имеет координаты (0,0), т.е. (x,y)==(x,x*x). Итак, самая нижняя точка параболы касается наклонной линии в точке (0,0).

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже