Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 53
Текст из файла (страница 53)
5Ьоы () г ) ) Выполнение этого кода дает следующий результат: Координаты точки а: 1, 2, 3 Координаты точки Ьг 10, 10, 10 Результат сложения а + Ь: 11, 12, 13 Результат сложения Ь + 10т 20, 20, 20 Результат сложения 15 + Ь1 25, 25, 25 Перегрузка операторов отношения Операторы отношения, например == и <, могут также перегружаться, причем очень просто. Как правило, перегруженный оператор отношения возвращает логическое значение Сгце и Та1зе. Это вполне соответствует правилам обычного применения подобных операторов и дает возможность использовать их перегружаемые разновидности в условных выражениях.
Если же возвращается результат другого типа, то тем самым сильно ограничивается применимость операторов отношения. Ниже приведен очередной вариант класса ТЬгееО, в котором перегружаются операторы < и >. В данном примере эти операторы служат для сравнения объектов тьгееО, исходя из их расстояния до начала координат. Один объект считается больше другого, если он находится дальше от начала координат.
А кроме того, один объект считается меньше другого, если он находится ближе к началу координат. Такой вариант реализации позволяет, в частности, определить, какая из двух заданных точек находится на большей сфере. Если же ни один из операторов не возвращает логическое значение сгпе, то обе точки находятся на одной и той же сфере. Разумеется, возможны и другие алгоритмы упорядочения. // Перегрузить операторы < и >. цз1пя зуасеит // Класс для хранения трехмерных координат.
с1ааз Тпгееп ( Тпк к, у, т) // трехмерные координаты рцЫЬс Тпгееп() ( х = у = а = от рцЫРс ТЬгееп(ъпк 1, 1пс 3, 1пс к) [ х = Тт у = 3) к = Хг ) // Перегрузить оператор <. рцЫТс акаквс Ьоо1 орегаког <(ТЬгееп ор1, Тпгееп ор2) ( 268 Часть ), Язык Са 15 (Масп.зк(гт (ор1.х * ор1.х + ор1.у * ор1.у + ор1. г * ор1. я) < магп.зк(гг (ор2.х * ор2.х е ор2.у * ор2.у + ор2.
я * ор2. я) ) геснгп Ггне; е1ве гесигп Та1век ) // Перегрузить оператор >. рньатс всагтс ьоо1 оретагог >(тптееО ор1, тьгееО ор2) ( 15(маГЬ.БЧгс(ор1.х * ор1.х + ор1.у * ор1.у + ор1.г * ор1.я) > мать.зк(гг (ор2.х * ор2.х + ор2.у * ор2.у + ор2. я * ор2. я) ) гегчгп стае; е1яе геситп Та1ве( ! // Вывести координаты Х, у, Е. рпЬТтс чо1<( Бпою() ( Сопяо1е.йг1те11пе(х + ", " + у т ", " + я); ) ) с1аяв ТЬгееРОено ( всастс чо1о Ма1п М ( Тпгеей а = лен Тпгее0(5, б, 7); ТЬгееО Ь = печ ТпгееО(10, 10, 10); ТПгеео с = пен ТЬгее0(1, 2, 3)/ ТЬгееО к( = пен Тпгее0(6, 7, 5); Сопяо1е.йг1се("Координаты точки а.БЬон()) Сопво1е.Игтсе("Координаты точки Ь.БЬон(); Сопво1е.йгтсе("Координаты точки с.БПон(); Сопво1е.йттге("Координаты точки Б.БЬою()) Сопво1е.Игтсе01пе()к а: "): с: ")' оы ")( 1Т(а > с) сопяо1е.иг1ге01пе("а > с истинно" ) к 1Т(а < с) сопво1е.иттге11пе("а < с истинно"); 1Т(а > Ь) Сопво1е.йг1се11пе("а > Ь истинно")к 11(а < Ь) Сопво1е.йг1те01пе("а < Ь истинно"); 1т(а > к() сопяо1е.иг1геОТпе("а > к)истинно"): е1ве тТ (а < «() Сопяо1е.йгтсе01пе ("а < к( истинно"); е1яе Сопво1е.йгттеЬТпе("Точки а и «(находятся на одном расстоянии " + "до начала отсчета"); Глава в.
Нврвгрузка операторов 269 Вот к какому результату приводит выполнение этого кода: Координаты точки а: 5, б, 7 Координаты точки Ь: 10, 10, 10 Координаты точки с: 1, 2, 3 Координаты точки «(: б, 7, 5 а > с истинно а < Ь истинно точки а и к( находятся на одном расстоянии до начала отсчета На перегрузку операторов отношения накладывается следующее важное ограничение: они должны перегружаться попарно. Так, если перегружается оператор <, то следует перегрузить и оператор >, и наоборот. Ниже приведены составленные в пары перегружаемые операторы отношения.
И еще одно замечание: если перегружаются операторы == и (=, то для этого обычно требуется также переопределить методы ОЬбесс. Е<(иа1в () и ОЬбесс. ЯесназЬСог(е () . Эти методы и способы их переопределения подробнее рассматриваются в главе 11. Перегрузка операторов ~где и йа1зе Ключевые слова Ьгие и Та1зе можно также использовать в качестве унарных операторов для целей перегрузки.
Перегружаемые варианты этих операторов позволяют определить назначение ключевых слов стае и Ха1зе специально для создаваемых классов. После перегрузки этих ключевых слов в качестве унарных операторов для конкретного класса появляется возможность использовать объекты этого класса для управления операторами 11, нЫ1е, Тот и <)о-ыЬ11е или же в условном выражении?.
Операторы сгие и Та1зе должны перегружаться попарно, а не раздельно. Ниже приведена общая форма перегрузки этих унарных операторов. риЬ11с всас1с Ьоо1 орегаког Стае (тип параметра операнд) ( // Возврат логического значения Стае или Га1зе. ) риЬ11с воаоъс Ьоо1 орегасог Га1ве (тип параметра операнд) // Возврат логического значения Сгое или Га1зе.
) Обратите внимание на то, что и в том и в другом случае возвращается результат типа Ьоо1. Ниже приведен пример программы, демонстрирующий реализацию операторов сгне и Та1зе в классе ТЬгее0. В каждом из этих операторов проверяется следующее условие: если хотя бы одна из координат объекта типа тьгееП равна нулю, то этот объект истинен, а если все три его координаты равны нулю, то такой объект ложен.
В данном примере программы реализован также оператор декремента исключительно в целях демонстрации. 270 Часть (, Язык С№ // Перегрузить операторы Ггие и Та1яе для класса ТЬгееО. ия1пд Вуясеи; //.Класс для хранения трехмерных координат. с1аяя ТЬгееО ( гпг х, у, г7 // трехмерные координаты рпЬ1гс ТпгееО() ( х = У = Я = 07 ) риЬ11с ТЬгееР(1пг г, Тпг 7, 1пс К) ( х = 11 у = 7; Я = К; ) // Перегрузить оператор Ггпе. риь1№с ягаггс ьоо1 орегагог ггое(тьгееО ор) ( 1й((ор.х )= О) () (ор.у 1= О) )) (ор.я != О)) гегнгп ггне7 // хотя бы одна координата не равна нулю е1яе гесигп Та1яе7 ) // Перегрузить оператор Та1яе. рпЬ1№с ясаС1с Ьоо1 орегагог Еа1яе(ТЬгееО ор) ( 1й((ор.х == О) яа (ор ° у == О) аа (ор ° я == О)) гегпгп ггпе7 // все координаты равны нулю е1яе гегигп Та1яе7 // Перегрузить унарный оператор — .
риЬ1гс ясасгс ТпгееО орегасог — (ТЬгееР ор) ( ТпгееР геяи1Г = пен ТЬгееР(); // Возвратить результат декрементирования. геяп1с.х = ор.х — 1; геяо1с.у = ор.у " 1; геяп1с.г = ор.з — 1; геспгп геяи1Г; ) // Вывести координаты Х, У, Е. риЬ1№с чо№б 5Ьои() ( Сопяо1е.иг(ге(гпе(х + ", " + у + ", " + г) ) ) с1аяя Тгиеуа1яеОеюо ( ясасгс ко10 Магп() ( ТЬгееО а = пеи ТЬгееР(5, б, 7)7 ТЬгееО Ь = пен ТЬгееО(10, 10, 10) ТЬгееО с = пеи ТЬгееР(0, О, О)) Глава 8. Перегрузка операторов 271 Сопво1е.иг1се("Координаты точки а: ")( а.зла()г Сопво1е.нгъке("Координаты точки Ь: ")т Ь.ЯЛон() г Сопво1е.нг1се("Координаты точки с: ")т с.б Пои (); Сопво1е.Игъсеьъпе(); 18(а) сопяо1е.игвгеувпе("точка а истинна."); е1ве Сопво1е.нгакеьъпе("Точка а ложна."); 18(Ь) Сопяо1е.нгъсеувпе("Точка Ь истинна."); е1яе Сопво1е.игъсетвпе("Точка Ь ложна."); гб(с) Сопяо1е.Иг1сегвпе("Точка с истинна."); е1ве Сопяо1е.Иг1кеьъпе("Точка с ложна.")т Сопяо1е.нгггеъъпе () г сопяо1е.игвгетьпе("управление циклом с помощью объекта класса тьгеев.")т г(о ( Ь.ЯЬои()т Ь вЂ” 7 ) ип11е(Ь)г ) ) Выполнение этой программы приводит к следующему результату: Координаты точки а: 5, 6, 7 Координаты точки Ь: 10, 10, 10 координаты точки с: О, О, 0 Точка а истинна Точка Ь истинна Точка с ложна Управление циклом с помощью объекта класса Тпгеео.
10, 10, 10 9, 9, 9 8, 8, 8 7, 7, 7 б, б, 6 5, 5, 5 4, 4, 4 3, 3, 3 2, 2, 2 1, 1, 1 Обратите внимание на то, как объекты класса ТЬгее() используются для управления условным оператором 15 и оператором цикла с(о-иь11е. так, в операторах 15 объект типа тнгеер проверяется с помощью оператора сгпе. Если результат этой проверки оказывается истинным, то оператор 11 выполняется. А в операторе цикла г)о-ИЬ11е объект Ь декрементируется на каждом шаге цикла. Следовательно, цикл повторяется до тех пор, 272 часть (. язык св пока проверка объекта Ь дает истинный результат, т.е, этот объект содержит хотя бы одну ненулевую координату. Если же окажется, что объект Ь содержит все нулевые координаты, его проверка с помощью оператора сгпе даст ложный результат и цикл завершится.
Перегрузка логических операторов Как вам должно быть уже известно, в С(г предусмотрены следующие логические операторы: й, (, !, йй и ( (. Из них перегрузке, безусловно, подлежат только операторы й, ! и! . Тем ие менее, соблюдая определенные правила, можно извлечь также пользу из укороченных логических операторов й й и ( (. Все эти возможности рассматриваются ниже. Простой способ перегрузки логических операторов Рассмотрим сначала простейший случай. Если не пользоваться укороченными логическими операторами, то перегрузку операторов й и ( можно производить совершенно естественным путем, получая в каждом случае результат типа Ьоо1.
Аналогичный результат, как правило, дает и перегружаемый оператор ! . Ниже приведен пример программы, в которой демонстрируется перегрузка логических операторов !, й и ( для объектов типа ТЬгееО. Как и в предыдущем примере, обьект типа ТЬгееО считается истинным, если хотя бы одна из его координат не равна нулю. Если же все три координаты объекта равны нулю, то он считается ложным. // Простой способ перегрузки логических операторов // (, ( и й длл объектов класса тпгееО. пя1пд Зуясеий // Класс для хранения трехмерных координат. с1аяя ТЬгееп ( 1пс х, у, г; // трехмерные координаты роЬ11с Тпгееп Н ( х = у = г = О( ) рпЬ11с Тпгееп(гпс 1, 1пг 1Ь гпс Х) ( х = гй у = 1; г = Гы ] // Перегрузить логический оператор (. рпЬ11с ясас1с Ьоо1 орегасог ((Тпгееп ор1, Тпгееп ор2) ( 11( ((ор1.х != О) (> (ор1.у != О) (( (ор1.г != О]) ((ор2.х != О) (( (ор2.у != О) (] (ор2.г != О) ) > гегпгп ггие> е1яе гесигп Га1яе; // Перегрузить логический оператор й.
роь1гс ягаггс ьоо1 орегагог й(тпгееО ор1, тпгееп ор2) ( 11( ((ор1.х != О) йй (ор1.у (= О) йй (ор1.г != О) ) й ((ор2.х != О) йй (ор2.у != О) йй (ор2.г != О)) ) гегогп ггое; е1яе гесигп Га1яей Глава 9. Перегрузка операторов 273 ,гг' Перегрузить логический оператор !. роЬ11с зеак1с Ьоо1 орегаоог !(Тпгее0 ор) ( та((ор.х != О) (( (ор.у != О) ! ( (ор.з ! О) ) гекпгп Еа1зег е1зе гекпгп Свое) // Вывести координаты Х, у, 2. рпЬ11с чоаб 5пон() ( Сопзо1е.Игаае)тле(х + ", " + у + ", " + з) т ) с1азв Тгпеуа1зеОеио ( зсасас чо1б Ма1п() ( Тпкеер а = пен ТЬкее0(5, 6, 7)Г Тпгеео Ь = лен ТЬкеео(10, 10, 10) ТЬгееР с = пеи ТЬкееО(0, О, О)) Сопзо1е.итаке("Координаты точки а: ")7 а.зЬон(); Сопзо1е.иг1ке("Координаты точки Ь: ")7 Ь.5пон()) Сопзо1е.иг1се("Координаты точки ст ")) с.зпон()т Сопзо1е.игтеет апе () 7 12((а) Сопзо1е.иг1ке11пе("Точка а ложна.")г 12(!Ь) Сопзо1е.ХгакеВТпе("Точка Ь ложна.")( 12((с) Сопзо1е.Иг1Сетапе("Точка с ложна."); Сопзо1е.иг1кевапе()т 12(а е ь) сопзо1е.игасеьапе("а е ь истинно.'") е1зе сопзо1е.хг1сеьапе("а в ь ложно."); 12(а а с) сопзо1е.иг1сеьапе("а а с истинно."); е1зе сопзо1е.ик1сеьапе["а а с ложно."); (т(а ( ь) сопзо1е.игасеьапе("а ! ь истинно."); е1зе Сопзо1е.иг1ке11пе("а ( Ь ложно.")т 12(а ( с) Сопзо1е.Игакетапе("а ! с истинно."); е1зе Сопзо1е.игаке11пе("а ( с ложно.")т ) При выполнении атой программы получается следующий результат: Координаты точки а: 5, 6, 7 Координаты точки Ь: 10, 10, 10 274 Часть (.
Язык С№ Координаты точки с: О, О, О Точка с ложна. а й Ь истинно. а й с ложно. а ) Ь истинно. а ) с истинно. При таком способе перегрузки логических операторов й, ) и ! методы каждого из них возвратцают результат типа Ьоо1. Это необходимо для того, чтобы использовать рассматриваемые операторы обычным образом, т.е. в тех выражениях, где предполагается результат типа Ьоо1. Напомним, что для всех встроенных в С№ типов Лянных результатом логической операции должно быть значение типа Ьоо1. Поэтому вполне разумно предусмотреть возврат значения типа Ьоо1 и в перегружаемых вариантах этих логических операторов. Но, к сожалению, такой способ перегрузки пригоден лишь в том случае, если не требуются укороченные логические операторы. Как сделать укороченные логические операторы доступными для применения Для того чтобы применение укороченных логических операторов ай и !! стало возможным, необходимо соблюсти следующие четыре правила.