Препроцессорная обертка
Как правило, код расположен не в одном файле. И подключение заголовочных файлов выполняется не обязательно в главном файле. Поэтому существует вероятность многократного включения в программу заголовочного файла, что в свою очередь приводит к ошибке компиляции:
Чтобы не возникало такого рода ошибок, в С++ существует специальная структура кода, которую ещё называют препроцессорная обёртка:
Данная препроцессорная обёртка предотвращает попытку многократного включения заголовочных файлов. Препроцессорные директивы обрабатываются до этапа компиляции, программой-препроцессором, который не допускает многократного определения одного и того же класса. Директива #ifndef проверяет, определено ли имя DATA_H, если нет, то управление передаётся директиве #define и определяется интерфейс класса. Если же имя DATA_H уже определено, управление передаётся директиве #endif, пропуская определение класса.
Обратите внимание на то, как написано имя класса, используемое в сочетании с директивами препроцессорной обёртки - DATA_H: в имени заголовочного файла, в котором объявлен класс, символы переведены в верхний регистр, а вместо точки - символ нижнего подчёркивания.
С использованием препроцессорной обёртки, попытки подключения одного и того же файла, ошибки переопределения не вызовут. Этот же приём применяется и для предотвращения многократного определения функций, если они вынесены в отдельный файл. Лабораторная работа № 11. Классы Продолжительность – 4 часа. Максимальный рейтинг – 8 баллов. Цель работы Научиться создавать класс и описывать его свойства и методы. Изучить спецификаторы доступа private и public. Освоить применение конструктора, деструктора, set- и get- методов. Освоить работу с объектами класса: корректно создавать, инициализировать, получать значения свойств, визуализировать и удалять. Научиться выделять память под динамические объекты класса и освобождать ее. Освоить обращение к свойствам и методам динамических объектов. Научиться программировать интерфейс класса и реализацию класса в соответствующих *.h и *.cpp файлах, корректно подключать их к проекту, используя препроцессорную обертку. Задание на лабораторную работу 1. Задать класс, реализующий операции с данными, в соответствии с индивидуальным заданием (Таблица 14). 2. Написать конструктор и деструктор класса. 3. Свойства объектов класса хранить со спецификатором private. Написать методы set и get обращения ко всем свойствами класса. 4. Написать метод визуализации (вывода на экран) свойств класса. 5. Интерфейс, реализацию и вызов объектов класса запрограммировать в трех различных файлах: класс.h, класс.cpp и main.cpp – соответственно. 6. В главной программе продемонстрировать работу со статическими и динамическими переменными – объектами класса: корректно создать, заполнить данными, визуализировать и удалить. 7. В отчете привести листинг программы, скриншоты тестирования программы, рисунок структуры класса. Листинг программы без комментариев не принимается.
Таблица 14 Варианты индивидуальных заданий
Наследование
Наследование – это механизм создания нового класса на основе ранее созданного. Наследование имеет смысл, если множество разнородных объектов имеют общие характеристики или функции. Рассмотрим пример классов для работы с графическими примитивами (прямая линия, эллипс, прямоугольник и пр.). Для любых графических объектов тип, цвет и толщина линии, координаты описываются одинаково на уровне языка программирования и логически отностятся к одной категории – свойства графического примитива. Поэтому эти элементы целесообразно выделить в отдельный класс – базовый и на основе него создавать новые классы – дочерние для более детального описания линии, эллипса и прямоугольника. Создадим базовый класс CPos, содержащий общую для графических объектов информацию, а на основе CPos можно построить дочерние классы для более детальной работы с графическими объектами, используя механизм наследования.
Cоздадим дочерний класс с именем CLine для работы с линией на основе базового CPos. Для этого после имени дочернего класса CLine ставится символ «:», а затем пишется имя базового класса CPos с указанием уровня доступа:
Уровень наследования public определяет доступ класса CLine ко всем переменным и функциям класса CPos, которые не являются частными (private). Переменные X1, Y1, X2 и Y2 описаны в разделе protected для возможности их использования в методе Draw() дочернего класса CLine, но они недоступны извне. Метод Draw() предназначен для визуализации графического объекта, но, изучение графических библиотек не входит в данный курс, и программирование ведется на уровне консольных приложений, в методе Draw() выводится текст, а не рисунок. Метод SetParam(int, int, int, int) задания координат графического объекта целиком находится в базовом классе CPos и по мере необходимости используется в дочернем классе CLine. В классе CLine два конструктора, при создании объекта line1 (экземпляра) класса CLine, выполняется сначала конструктор по умолчанию CPos() базового класса, а затем тело конструктора дочернего – CLine().
В случае вызова конструктора с параметрами CLine(int, int, int, int) для создания экземпляра line2, выполняется конструктор по умолчанию CPos() базового класса, а затем тело конструктора CLine(int, int, int, int) дочернего класса, в котором выполняется функция SetParam(int, int, int, int) для записи значений координат графического объекта. Использовать только конструктор по умолчанию не всегда удобно. Можно указать явно, какой конструктор базового класса вызывать из конструктора класса-потомка:
Теперь конструктор CLine() будет вызывать конструктор CPos() базового класса, а конструктор с параметрами CLine(int, int, int, int) будет вызывать конструктор CPos(int, int, int, int). При этом функция SetParam() в теле конструктора CLine(int, int, int, int) не нужна, т.к. необходимая инициализация переменных будет выполнена при вызове конструктора с параметрами CPos(int, int, int, int) базового класса.
В рассматриваемой задаче, класс CPos является вспомогательным, при этом нет необходимости создавать его экземпляр для непосредственной работы с ним. Поэтому целесообразно защитить его от возможности создания, поместив конструкторы данного класса в раздел protected. Такие классы называются абстрактнымиклассами, т.е. они не могут существовать как самостоятельные объекты, а служат для создания новых, дочерних классов. Public- функции абстрактных классов CPos можно вызывать, например, через объект класса-потомка CLine:
Для работы с другими графическими примитивами (прямоугольником и эллипсом) подобным образом можно создать дочерние классы от CPos, отличающиеся друг от друга реализацией функции Draw():
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|