Пример выполнения задания d (1012883), страница 4
Текст из файла (страница 4)
Мы договорились перед началом решения задачи, что треугольники будут задаваться перечислением нх вершин в порядке изображения их на плоскости но часовой стрелке. То есть каждая пара вершин ' образует вектор, и эти векторы следуют один за другим по часовой стрелке. При этом условии некоторая точка находится внутри треугольника тогда и только тогда, когда ее ориентация относительно каждой вектора-стороны треугольника имеет одно из двух значений; либо й!6НТ, либо ВЕТИЕЕМ. Эту подзадачу будет ре- шать метод 1пТг1 апд1 е() в классе Ро1 п2. Изложим по порядку, какие изменения нужно внести в тексты модулей. 1. Модуль Ротпг П, О Добавьте перед объявлением класса Ро1 п2 объявление нового типа Ой1 ЕМТ, а также упреждающее объявление типа Тгт апд1 е: ения Ой1ЕИТ ( СЕЕТ, й!6НТ, АНЕАО, ВЕН1МО, ВЕТИЕЕМ ); с1авв Тгтапд)е: Последнее необходимо, чтобы имя типа Тг1 апд)е было известно компилятору в данной единице трансляции, так как оно используется в сигнатуре метода !пТг1апд)е().
О Добавьте внутри класса Ро1 п2 объявления функций: Ро1п2 орегасог +(Ро(п26): Ро1п2 орега2ог -(Ро(п2в): ' Точнее говоря, от воображаемого бесконечного вектора, поскольку направление здесь очень важно. г)оиЬ)е Сепдсп() сопэ2 // определяет длину вектора точки // в полярной,систене координат Ой1ЕМТ С)авв1/у(Ро1п26, Ро1п2$) сопв2: // определяет полояение точни // относительно вектора, // заданного двуня точками Ьоо1 !пТгтапд1е(Тг1апд!еа) сопв2; // определяет, // находится ли точка внутри // треугольника Функция-операция <-» и метод Сепдсщ) будут использованы при реализации метода С1авэтсуО, а функция-операция <+» добавлена для симметрии.
Метод С)азв(Ту(), в свою очередь, вызывается из метода 1пТгтапд1е(). 1. Модуль Ротп2.срр. О ДобавьтепоследирективыУ1пс1цде <1оэ2геаа директиву(/1пс1иг)е яасп.п>. Она необходима для использования функции вдг2(х) из математической библиотеки С++ в алгоритме метода Еепд2ЬО. О Добавьте после директивы (/1 пс1 аде «Рот п2. Ьь директиву 01 пс1цг(е «Тг1 апд1е.
П». О Последняя необходима в связи с использованием имени класса Тг) апд1 е в данной единице трансляции. О Добавьте реализацию функций-операций: Ротпс Ро1п2:;орегасог +(Ро1п20 р) ( гесигп Ро1п2(х + р х у + р у). Ротп2 Ротпс орегасог (Ротпсд р) ( гесигп Ро1п2(х - р.х, у - р у); О Добавьте реализацию метода Еепд2П(): г(оиЬ)е Ротпс гЕепдсп() сопв2 ( гесцгп вдг2(х*х + у»у); О Добавьте реализацию метода С1авэ(ТуО: Ой1ЕМТ Ро1п2::С1авз(Ту(Ро(п26 Ьед р. Ро(псд епг( р) сопв2 ( Ротпс рд - *2Ь1э: Ротпс а = епи' р - Ьед р; Ротпг Ь рд Ьсд р г(оиЬ)е ва - а.х * Ь.у - Ь,х * а.уг 1Т (ва > 0.0) ге2игп СЕЕТ: 12 (за < 0.0) гесигп й!6НТ: 11 ((а.х * Ь.х < 0.0) (/ (а.у * Ь.у < 0,0)) гесигп ВЕН1МО: 1т (а.( епд2Ы ) < Ь.$.епд2П()) ге2цгп АНЕАО: гесигп ВЕТИЕЕМ, Алгоритм заимствован из 161, поэтому мы не будем здесь подробно его разбирать.
Обратите внимание, что аргументы передаются в функцию по ссылке — это позволяет избежать вызова конструктора копирования. О Добавьте реализацию метода )пТг1апд)е(): Ьоо) Ро(п[::1пТгтапд1е(Тг1апд1еа 1гта) сопя! [ ОН1ЕМТ ог1 - С1авв!Ту(вгта.бе! чП ). Ег1а.бег ч2()); ОН1ЕМТ ог2 - С1авв1[у(ьг1а.бе! ч2(), Ьгта.бе1 чЗ()): ОН1ЕМТ огЗ - С1авв1[у(сг1а.бе1 чЗ(), Ьгта.бес ч1()); 1Т ((ог1 = Д16НТ П ог1 — ВЕТНЕЕМ) Ы (ог2 — Н16НТ !( ог2 == ВЕТНЕЕМ) ав (огЗ == Й16НТ !( огЗ -= ВЕТНЕЕМ)) геьигп сгие; е1ве гевцгп Та1ве; 2. Модуль Тг!апд)е.Л: добавьте в классе Тгтапд1е объявление дружественнои функции (все равно, в каком месте): Тг)епт( Ьао1 Тг!а!пТг1а(Тг(апд1е, Тг!апд1е); // Определить, // входит ли один треугольник во второй 3.
Модуль Тг1 апд)е. срр: добавьте в конец файла реализацию внешнеи дружественной функции: // Определить. входит ли треугольник Ьг1а1 в треугольник Ьг1а2 Ьоо1 Тг!а!пТг1а(Тг!апд1е сгта1. Тг1апд)е Ьг(а2) ( Ротп! ч1 - 1г)а1.6ес ч1(); Ро1п1 ч2 = тг1а1.6е1 ч2(): Ротпс чЗ - 1г1а1.бес чЗ(); ге!игл (ч1.1пТг(апд1е(сг(а2) а$ ч2.!пТг!апд1е([гта2) Ы ч3.1пТг!апд1е(сг!а2)); ге1игп тгие; ) Результат, возвращаемый функцией, основан на проверке вхождения каждой вершины первого треугольника (1ю а1) во второй треугольник (гг1а2).
4. Модуль На!п. срр: замените заглушку функции 1в1пс1иоец() следующим кодом: // — определение отношения включения чотт) !в1пс)исегНТшапд)е* р Сг!а[], !и! 'к) ( соцт « "== — = Отношение включения ==-====--" « еп()1: сонь « "Введите ноиер 1-го треугольника (от 1 до " « к « ")т ": 1пт !1 = бевйишоег(1, Е) - 1; соцс « "Введите нокер 2-го треугольника (от 1 до " « к « "): !пг 12 = бесйишЬег(1, к) — 1; !Т (Тг1а1пТг1а("р Ьг1а[1 Ц . *р 1г!а[!2])) сои! р тг!а[1 Ц ->бесйаше() « " - входит в « р гг!а[12]- бетйаше() « епФ: е1ве сонг р Сг!а[! Ц ->бе1йаше() « " — не входит в « р 1г1а[12]->бе!Маше() « еп41: Ех116асй(); Модификация проекта завершена. Откомпилируйте и запустите программу. Выберите четвертый пункт меню,.
Следуя указаниям программы, введите номера сравниваемых треугольников, например 1 и 2. Вы должны получить следующий результат: 4 — Отношение включения Введите непер 1-то треугольника (от 1 до 4): 1 Введите номер 2-го треугольника (от 1 до 4): 2 Сору сопввгисгог Гог: тшаВ Сору сопвсгис1ог Тог: Гг(ад Оеввгиссог Рог: Ьг1ад(копия) Оевсгис1ог Тот: Ьг(аВ(копия) Треугольник 1 - входит в - Треугольник 2 Накиите Епвег Обратите внимание на отладочную печать: конструкторы копирования вызываются при передаче аргументов в функцию Тг1а!пТг1а(), а перед возвратом из этой функции вызываются соответствующие деструкторы.
Проведите следующий эксперимент: удалите с помощью скобок комментария конструктор копирования в файлах Тгтапд1е. Ь и Тг(апд1е.срр, откомпилируйте проект и 'повторите тестирование четвертого пункта меню. Полюбовавшись результатом, верните проект в нормальное соотояние. Протестируйте остальные пункты меню, вызывая их в произвольном порядке.
Когда вы сочтете, что тестирование завершено, уберите с помощью символов комментария // всю отладочную печать из конструкторов, деструктора и операции присваивания. Повторите тестирование без отладочной печати. Решение задачи 1.2 завершено. Давайте повторим наиболее важные моменты этого семинара. 1. Использование классов лежит в основе объектно-ориентированной декомпозиции программных систем, которая является более эффективным средством борьбы со сложностью систем, чем функциональная декомпозиция.
2. В результате декомпозиции система разделяется на компоненты (модули, функции, классы). Чтобы обеспечить высокое качество проекта, его способность к модификациям, удобство сопровождения, необходимо учитывать сцепление внутри компонента (оно должно быть сильным) и связанность между компонентами (она должна быть слабой), а также правильно распределять обязанности между компонентом-клиентом и компонентом-сервером. 3. Класс — это определяемый пользователем тип, лежащий в основе ООП.
Класс содержит ряд полей (переменных), а также методов (функций), имеющих доступ к этим полям. 4, Доступ к отдельным частям класса регулируется с помощью ключевых слов: раЬ31с (открытая часть), рг1'таге (закрытая часть) и ргоСесгеб (защищенная часть). Последний вид доступа имеет значение только прн наследовании классов.
Методы, расположенные в открытой части, формируют интерфейс класса и могут вызываться через соответствующий объект. 5. Если в классе имеются поля типа указателей и осуществляется динамическое выделение памяти, то необходимо позаботиться о создании конструктора копирования и перегрузке операции присваивания. 6. Для создания полного, минимального и интуитивно понятного интерфейса класса широко применяется перегрузка методов и операций.
.