Г. Шилдт - С# 3.0 Полное руководство. 2010 (1160798), страница 54
Текст из файла (страница 54)
Во-первых, в классе должна быть произведена перегрузка логических операторов й и ). Во-вторых, перегружаемые методы операторов й и ) должны возвращать значение того же типа, что и у класса, для которого эти операторы перегружаются. В-третьих, каждый параметр должен содержать ссылку на объект того класса, для которого перегружается логический оператор. И в-четвертых, для класса должны быть перегружены операторы сгпе и Та1ве. Если все эти условия выполняются, то укороченные логические операторы автоматически становятся пригодными для применения. В приведенном ниже примере программы показано, как правильно реализовать логические операторы й и ! в классе тьгееО, чтобы сделать доступными для применения укороченные логические операторы й й и !! .
/* полее совершенный способ перегрузки логических операторов !, ! и й для объектов класса Тьгеев. В этом варианте укороченные логические операторы йй и (( становятся доступньвки для применения автоматически. */ оа1пп зуагевт // Класс для хранения трехмерных координат. с1азв Твгеев ( 1пг х, у, з; // трехмерные координаты рпЫгс Тпгеев() ( х = у = х = О; ) рпЫгс Тпгееб(гпк г, Тпс 3, 1пс К) ( х = г) у = Зт г К) ) // Перегрузить логический оператор ) для укороченного О вычисления.
роЫ1с вгаейс тнгеев орегагог ((тьгееО ор1, тьгееО ор2) Глава 9. Перегрузка операторов 275 ( ТТ( ((ор1.х != О) (! (ор1.у != 0) (( (ор1.г (= О) ) ((ор2.х (= О) (( (ор2.у != О) (( (ор2.к != 0)) ) геспгп пен ТпгееО(1, 1, 1)г е1яе гекигп пен ТЬгееО(0, О, 0)т ) // Перегрузить логический оператор Ь для укороченного // вычисления. рпЫ1с ягагас тпгее0 орегагог ь(тьгееО ор1, тпгееО ор2) ( 1Е( ((ор1.х != О) ьь (ор1.у != О) ьь (ор1.к )= О) ) ь ((ор2.х (= 0) ьь (ор2.у )= О) ьь (ор2.к != О) ) ) гекогп пен ТпгееР(1, 1, 1)т е1яе гекогп пен ТЬгееО[0, О, 0)т ) // Перегрузить логический оператор !. роЫТс якак1с Ьоо1 орегаког !(ТЬгее0 ор) ( 11(ор) гекпгп Та1яет е1яе геспгп стает ) // Перегрузить оператор Ггие.
роЬ11с якакас Ьоо1 орегаког Ггое(тпгееО ор) ( 11((ор.х != О) (( (ор.у != О) !! (ор.я (= О)) гегигп ггоет // хотя бы одна координата не равна нулю е1яе гегигп Та1яет ) // Перегрузить оператор Та1яе. риЬ11с якасас Ьоо1 орегасог Та1яе(ТЬгее0 ор) ( ТТ((ор.х == О) ьь (ор.у == О) ьь (ор.к == О)) гекогп Ггпет О все координаты равны нулю е1яе гесогп Та1яе) // Ввести координаты Х, У, 2. роЫТс чо1г) Бпон() ( Сопяо1е.нг1сеОТпе(х ь ", " ь у + ", " + я); ) ) с1аяя Тгоеуа1яеОеюо ( ягаг1с чоьг( Маго () ( ТпгееО а = пен ТЬгееР(5, б, 7) т ТагееО Ь пен ТЬгеео(10, 10, 10)т 276 Часть !, )(эык С№ ТпгееР с = пен ТЬгееО(0, О, О) сопво1е.иггге("координаты точки а: ")) а. Опон () ) Сопво1е.йг1се("Координаты точки Ь: "); Ь.Опон()! Сопво1е.йг1ге("Координаты точки с: ")! с.апоы() ! Сопво1е.Иггсейьпе()) 1№(а) сопво1е.игагеьапе("точка а истинна.")! 1Т(Ы Сопво1е.йг1се11пе("'Точка Ь истинна."); 1Е(с) Сопво1е.Иг1сейьпе("Точка с истинна."); 1Е()а) Сопво1е.йг1се11пе("Точка а ложна."); 1№()Ы Сопво1е.Иг1сейапе("Точка Ь ложна."); 1Е()с) Сопво1е.Игггекьпе("Точка с ложна."); Сопво1е.йг1ге11пе() сопво1е.иг1ге11пе("применение логических операторов а и !")! 11(а 6 ы сопво1е.игасеь№пе("а з ь истинно."); е1яе сопво1е.иг1геьапе("а а ь ложно."); 11(а а с) Сопяо1е.йг1геыьпе("а а с истинно.")! е1ве Сопяо1е.йг1геы№пе("а а с ложно."); 11(а ! Ы Сопяо1е.йг1сеыапе("а ! Ь истинно.")! е1ве Сопво1е.йггсеьапе("а ! Ь ложно.")1 11(а ! с) Сопяо1е.йгасеЬгпе("а ! с истинно."); е1ве Сопво1е.Игггеьгпе("а ! с ложно.")т Сопво1е.йг1сеь1пе() // А теперь применить укороченные // логические операторы.
Сопво1е.йг1гейьпе("Применение укороченных" + "логических операторов ва и )!")> 11(а ва ы сопво1е.иг1геь№пе("а аа ь истинно."); е1ве сопво1е.иг1геь1пе("а аа Ь ложно."); 11(а за с) Сопво1е.иг1се11пе("а ав с истинно."); е1ве сопво1е.иг№геьапе("а ва с ложно.")т 11(а )! Ы сопво1е.игагеььпе("а )! ь истинно."); е1ве Сопво1е.йг1сейьпе("а )! Ь ложно."); 11 (а ! ! с) Сопяо1е.йгасет Ьпе ("а ! ! с истинно. "); е1ве Сопво1е.Иг1секьпе("а )! с ложно."); ) ) Глава 9.
Перегрузка операторов 277 Выполнение этой программы приводит к следующему результату: Координаты точки а: 5, б, 7 Координаты точки Ь: 10, 10, 10 Координаты точки с: О, О, 0 Точка а истинна Точка Ь истинна Точка с ложна. Применение логических операторов й и ( а й Ь истинно. а й с ложно. а ( Ь истинно. а ( с истинно, Применение укороченных логических операторов йй и (( а йй Ь истинно.
а йй с ложно. а !! Ь истинно. а !! с истинно. Рассмотрим более подробно, каким образом реализуются логические операторы й и (. Оии представлены в следующем фрагменте кода: // Перегрузить логический оператор ( для укороченного вычисления.
ривгас вкакйс Тпгеев орегаког ((ТЬгееО ор1, ТЬгееО ор2) ( 1Т( ((ор1.х!= О) !( (ор1.у!= О) (( (ор1.х (= О)) ! ((ор2.х != О) (( (ор2.у != О) (! (ор2.х != О) ) ) гекикп пен ТЬгееО(1, 1, 1)) е1ае гекигп пен ТЬгеео(0, О, О)) ) // Перегрузить логический оператор й для укороченного вычисления. рив11с акакйс Тпгееп орегакок й(ТЬгеео ор1, ТЬгееО ор2) ( ТТ( ((ор1.х != О) йй (ор1.у (= О) йй (ор1.2 (= О)) й ((ор2.х != О) йй (ор2.у != О) йй (ор2.х (= О)) ) гекигп пен ТЬгееО(1, 1, 1); е1ве гекикп пен Тпгееп(0, О, О); ) Прежде всего обратите внимание иа то, что методы обоих перегружаемых логических операторов теперь возвращают объект типа ТЬгееО. И особенно обратите внимание иа то, как формируется этот объект.
Если логическая операция дает истинный результат, то создастся и возвращается истинный объект типа ТЬгееО, у которого хотя бы одна коордииата ие равна нулю. Если же логическая операция дает ложный результат, то соответственно создается и возвращается ложный объект.
Таким образом, результатом вычислеиия логического выражения а й Ь в следующем фрагменте кода: 278 Часть (, Язык С№ 11(а а Ы Сопао1е.Игъкеъъпе("а а Ь истинно."); е1ае Сопао1е.икькеъъпе("а а Ь ложно.")! является объект типа тпкее(), который в данном случае оказывается истинным. А поскольку операторы Сгпе и га1зе уже определены, то созданный объект типа ТЬгееГ) подвергается действию оператора Сгце и в конечном итоге возвращается результат типа Ьоо1. В данном случае он равен Сгпе, а следовательно, условный оператор 11 успешно выполняется.
Благодаря тому что все необходимые правила соблюдены, укороченные операторы становятся доступными для применения к объектам тцгееп. Они действуют следующим образом. Первый операнд проверяется с помощью операторного метода орегасог 'сгпе (для оператора ) ) ) или же с помощью операторного метода орегаког га1зе (для оператора а а). Если удается определить результат данной операции, то соответствующий перегруженный оператор (ь или ) ) далее не выполняется. В противном случае перегруженный оператор (а или ( соответственно) используется для определения конечного результата.
Следовательно, когда применяется укороченный логический оператор за или ) (, то соответствующий логический оператор а или ) вызывается лишь в том случае, если по первому операнду невозможно определить результат вычисления выражения. В качестве примера рассмотрим следующую строку кода из приведенной выше программы: 11 (а ) ( с) Сопао1е.иг1ке11пе ("а ) ) с истинно."); В этой строке кода сначала применяется оператор Сгпе к объекту а.
В данном случае объект а истинен, и поэтому использовать далее операторный метод ) нет необходимости. Но если переписать данную строку кода следующим образом: 11(с () а) Сопао1е.ик11еъ1пе("с ) ) а истинно.") ) то оператор стае был бы сначала применен к объекту с, который в данном случае ложен. А это означает, что для определения истинности объекта а пришлось бы далее вызывать операторный метод ).
Описанные выше способ применения укороченных логических операторов может показаться, на первый взгляд, несколько запутанным, но по зрелом размышлении в таком применении обнаруживается известный практический смысл. Ведь благодаря перегрузке операторов Сгпе и га1зе для класса компилятор получает разрешение на применение укороченных логических операторов, не прибегая к явной их перегрузке. Это дает также возможность использовать объекты в условных выражениях. И вообще, логические операторы а и ) лучше всего реализовывать полностью, если, конечно, не требуется очень узко направленная их реализация.
Операторы преобразования Иногда объект определенного класса требуется использовать в выражении, включающем в себя данные других типов. В одних случаях для этой цели оказывается пригодной перегрузка одного или более операторов, а в других случаях — обыкновенное преобразование типа класса в целевой тип. Для подобных ситуаций в С№ предусмотрена специальная разновидность операторного метода, называемая оператором преобразования.
Такой оператор преобразует объект исходного класса в другой тип. Операторы преобразования помогают полностью интегрировать типы классов в среду программирования на С№, разрешая свободно пользоваться классами вместе с другими типами данных, при условии, что определен порядок преобразования к этим типам. Глава 9. Перегрузка операторов 279 Существуют две формы операторов преобразования: явная и неявная. Ниже они представлены в общем виде. риЫТс асасас ехр11сък ОРегагог целевой тип( нсходнтнй тип ч) (гекигп значение; ) риЫгс всасгс 1ир11сгс орегасог целевой тнп( исходный тнп ч) (гесигп значение;) где целевой тип обозначает тот тип, в который выполняется преобразование; исходный тип — тот тип, который преобразуется; значение — конкретное значение, приобретаемое классом после преобразования. Операторы преобразования возвращают данные, имеющие целевой тнп, причем указывать другие возвращаемые типы данных не разрешается.
Если оператор преобразования указан в неявной форме (1ыр11с1г), то преобразование вызывается автоматически, например, в том случае, когда объект используется в выражении вместе со значением целевого типа. Если же оператор преобразования указан в явной форме (ехр11сус), то преобразование вызывается в том случае, когда выполняется приведение типов. Для одних и тех же исходных и целевых типов данных нельзя указывать оператор преобразования одновременно в явной и неявной форме.