Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 82
Текст из файла (страница 82)
Такие иерархии идеальны для построения программ путем последовательных улучшений. Онн обеспечивают максимум поддержки для реализации новых классов до тех пор, пока новые классы точно вписываются в существующую иерархию. Классические иерархии имеют тенденцию смешивать вопросы реализации с предоставляемыми пользователям интерфейсами. Здесь могут помочь абстрактные классы. Иерархии абстрактных классов предоставляют ясный и мощный способ выражения абстрактных концепций, не загрязняя их деталями реализации и не требуя дополнительных накладных расходов.
В конце концов, вызов виртуальной функции обходится дешево и не зависит от того, к какой абстракции идет при этом обращение. Вызов члена абстрактного класса стоит не дороже вызова любой другой виртуальной функции. Логическим завершением этих размышлений будет система, представленная пользователям как иерархия абстрактных классов и реализованная при помощи классической иерархии. 12.6.
Советы 1. Избегайте полей типа; 912.2.5. 2. Используйте указатели и ссылки, чтобы избежать срезкн; 912.2.3. 3. Используйте абстрактные классы, чтобы сфокусироваться на предоставлении ясных интерфейсов; 912.3. 4. Используйте абстрактные классы лля минимизации интерфейсов; 912.4.2. 5. Используйте абстрактные классы для отделения деталей реализации от интерфейсов; 912.4.2. б.
Используйте виртуальные функции, чтобы обеспечить независимость пользовательского кода от добавления новых реализаций; 912.4.!. 7. Используйте абстрактные классы для минимизации необходимых перекомпиляций пользовательского кода; 912.4.2. 8. Используйте абстрактные классы для того, чтобы обеспечить сосуществование альтернативных реализаций; 912.4.3. 9. Класс с виртуальными функциями должен иметь виртуальный деструктор; $ ! 2.4.2.
398 Глава 12. Наследование классов 18. 11. 12.7. УПРажНЕНИЯ (*1) Пусть дано определение с(аюю Ьаюе ( рп0!юс: юлгюиа! го(ю! (аюп () (солю« "Ьаюе'~л" ю ) )ю 2. 3. 4. Абстрактный класс в типичном случае не нуждается в конструкторах; $12.4.2. Представления различных концепций должны содержаться раздельно; в 12.4.1.! . Напишите два производных от Ваке класса, и для каждого из них определите юаюп (), выводящую имя класса. Создайте объекты этих классов и вызовите юаюп() для них. Присвойте значения указателей на эти объекты указателю типа Вахе* и вызове с его помощью юаюп() .
(*3.5). Реализуйте простую графическую систему, используя доступные на вашем компьютере графические средства (если их нет — используйте АБСП-представление, где пиксел, это знакоместо): Ягюлю(оюг (и, юп) создает на экране область размером ихюл. Координаты декартовы. Окно юг типа Ягюлю!оюг имеет координаты н.спгюепю(). Начальные координаты равны Роюпю(0,0). Координаты можно задать с помощью я.
сиггелю(р), где р имеет тип Роли. Тип Роблю задается парой координат: Роюпю(х,у) . Тип 1!пе специфицируется парой точек: 1!ле (юг. сиггелю(), р2); класс Яюаре является общим интерфейсом для Рою, 1юпе, Вееюаля!е, С(гс!е и других фигур. Роюлю не является Ягоре. Рою(р) представляет точку р на экране. Яюаре на экране не наблюдается до вызова ю!гаюг() . Например: юг. ю!гаюг(С(гс!е(юг.сиггепюО, 10) ) . Каждый Ягоре имеет девять контактных точек: е (еахю), юг (югеюю), и (погй), ю (юоиюй), пе, пи, юе, ююг и с ( сепюег) . Например: 1лпе (х. с ( ), у. пв ( ) ) создает линию из центра х в левый верхний угол у. После вызова йав () для Я)аре его текущие координаты равны юе() . Вес!или!е определяется верхней левой и правой нижней вершинами: Вес!или!е(юг.сиггелю(), Роюпю(10, 10) ) .
В качестве простого теста изобразите простой детский рисунок «дом с крышей, два окна и дверь». (*2) Изображение Ягоре на экране компьютера выполняется в виде множества линейных сегментов. Реализуйте операции, варьирующие внешний вид этих сегментов: ю. юЬ!стезю(п) устанавливает толщину линии в О, 1, 2 или 3 единицы, где 2 соответствует умолчательному значению, а 0 — невидимой линии. Кроме того, сегменты могут быть юояю! (сплошная линия), ймйею! (пунктирная) и ю!лютею! (из точек), что устанавливается функцией Яюаре:: оию1юле() . (*2.5) Предоставьте функцию 1(лею:аггоюгйеаю!(), добавляющую стрелку к концу линии.
У линии два конца и стрелки могут указывать оба направления вдоль линии, так что аргументы функции аггоюгйеаю(() должны уметь задавать по крайней мере четыре альтернативы. 12.7. Упражнения 399 5. (*3.5) Предоставьте гарантии того, что точки и линии, не попадающие в пре делы %адом, не появятся на экране компьютера. Это часто называют «отсечением» (с11рр1пя). В качестве упражнения не пользуйтесь встроенными средствами вашей графической подсистемы. б. (*2.5) Добавьте тип Тех! к вашей графической системе.
Тех! — это прямо угольный Ягоре, внутри которого выводятся символы. По умолчанию, каждый символ занимает позицию в одну единицу по вертикали и горизонтали. 7. (*2) Определите функцию, которая рисует соединяющую две фигуры (типа Ягоре) линию, вычисляя для этого две «ближайшие точки» и соединяя их. 8. («3) Добавьте к вашей простой графической системе цвет. Цвет может быть у фона, внутренних областей замкнутых фигур и у контуров фигур. 9. (*2).
Рассмотрим: с!аз» Сваг гес ( йгзт сйаг с!степ! (71 риЫ!с: згаггс Сваг гес* пем сйаг»ес(!псе) г сйагь орега(ог() (гпг !) ( гетгп с!степ)(!); ) 77 ... )) Определите пеп сйаг гес(), вьиеляюшую непрерывную память для Сйаг гес таким образом, чтобы доступ к элементам мог осуществляться по индексу через е!етеп!. При каких обстоятельствах этот трюк может вызвать серьезные проблемы? 10. ('2.5) Для классов С(гс!е, Ядвиге и Тг!апа!е, производных от Я(аре, определите функцию !пгегзесг() (пересечение), которая принимает два аргумента типа Ягоре* и вызывает другие функции, необходимые для выявления возможности пересечения фигур.
Для решения этой задачи добавьте к классам соответствующие виртуальные функции. Можете не писать реальный код, выявляющий пересечение; просто убедитесь, что вызываются правильные функции. Решение таких задач называют двойной диспетчеризацией (доиЫе дгзрогсп) или мультиметодом (ти!гг-тег)гог!) . 11. (*5) Спроектируйте и реализуйте библиотеку для решения задач моделирова- ния, управляемых событиями.
Подсказка: <газ!«. !»>. Это, однако, старая программа, которую вы можете улучшить. Должен быть объявлен класс !ах!с, объекты которого могут сохранять состояние и восстанавливать его (функции газ!с: г ваге О и газ!с:: газ!иге () ), так что они могут работать как индивидуальные задачи. Частные задачи определяются с помощью классов, производных от газ!с. Задачи выполняют программы, специфицируемые их виртуальными функциями. Нужно реализовать возможность передачи параметров задаче с помощью аргументов конструкторов. Должен иметься планировщик (зс(зе((ц!ег) для реализации концепции виртуального времени.
Введите функцию газ)г::де!ау(!опя), которая «потребляет» виртуальное время. Сделать планировщик частью класса газ!с или нет — одно из ваших собственных важ- 4ОО Глава ) 2 Наследование классов нейших проектных решений. Задачи должны иметь возможность взаимодействовать друг с другом (сошпшп1саге). Разработайте для этого класс киеве (очередь сообщений). Придумайте, как задача могла бы ожидать ввод из разных очередей. Обрабатывайте ошибки времени выполнения единым образом. Как можно отлаживать программы, использующие такую библиотеку? 12. (*2) Определите интерфейсы для И~агпог (воин), Мопзгег (монстр) и ОЬ/еег (некий предмет, который можно поднять, бросить и т.д.), применяемых в ролевой игре.
13, (*).5) Почему одновременно есть и класс Ротб и класс Рог в 512.7[2)? При каких обстоятельствах будет хорошей идеей снабдить ойаре конкретными версиями ключевых классов вроде Хгяе? 14. (*3) Определите в общих чертах конкретные стратегии реализации примера Ба? Ьох (512.4), основываясь на идее о том, что каждый видимый приложению класс является интерфейсом, содержащим единственный указатель на реализацию. Таким образом, каждый интерфейсный класс будет выполнять роль дескриптора для класса реализации, и будут существовать иерархии интерфейсов и иерархии реализации.
Напишите фрагменты кода, иллюстрирующие возможные проблемы с приведением типов. Рассмотрите возможности упрощения использования, программирования, повторного применения интерфейсов и реализации при добавлении новых концепций к иерархии, упрощение модификации интерфейсов и реализации, а также необходимость перекомпиляции после внесения изменений в реализацию. Шаблоны Здесь — Ванга цитата. — Е Страуструп Шаблоны — шаблон строк — конкретизация шаблона — параметры шаблонов— проверка типа — шаблоны функций — выведение типов аргументов шаблона— задание аргументов шаблона — перегрузка шаблонов функций — выбор алгоритма через аргументы шаблона — аргументы шаблона по умолчанию — специализация — наследование и шаблоны — шаблонные члены шаблонов преобразования — организация исходного кода — советы — упражнения. 13.1.