Г. Шилдт - С#4.0 Полное руководство (1160795), страница 55
Текст из файла (страница 55)
Если удается определить результат данной операции, то соответствующий перегружаемый оператор (ь или () далее не выполняется. В противном случае перегружаемый оператор (а или ) соответственно) используется для определения конечного результата. Следовательно, когда применяется укороченный логический оператор за или ( (, то соответствующий логический оператор ь или ( вызывается лишь в том случае, если по первому операнду невозможно определить результат вычисления выражения.
В качестве примера рассмотрим следующую строку кода из приведенной выше программы. 11(а )) с) Сопяо1е.нггтеыпе("а (( с истинно.")з В этой строке кода сначала применяется оператор г гпе к объекту а. В данном случае объект а истинен, и поэтому использовать далее операторный метод ( нет необходимости.
Но если переписать данную строку кода следующим образом: 11 (с ) ) а) Сопяо1е.итгтеЫпе ("с ( ( а истинно. ")," то оператор стпе был бы сначала применен к объекту с, который в данном случае ложен. А это означает, что для определения истинности объекта а пришлось бы далее вызывать операторный метод ) . Описанный выше способ применения укороченных логических операторов может показаться, на первый взгляд, несколько запутанным, но если подумать, то в таком применении обнаруживается известный практический смысл.
Ведь благодаря перегрузке операторов Сгпе и Та1яе для класса компилятор получает разрешение на применение укороченных логических опера~оров, не прибегая к явной их перегрузке. Это дает также возможность использовать объекты в условных выражениях. И вообще, логические операторы ь и ) лучше всего реализовывать полностью, если, конечно, не требуется очень узко направленная их реализация. Операторы преобразования Иногда объект определенного класса требуется использовать в выражении, включающем в себя данные других типов.
В одних случаях для этой цели оказывается Глава 9. Перегрузка операторов 293 пригодной перегрузка одного или более операторов, а в других случаях — обыкновенное преобразование типа класса в целевой тип. Для подобных ситуаций в СФ предусмотрена специальная разновидность операторного метода, называемая оиярап(проз( преобразования. Такой оператор преобразует объект исходного класса в другой тип. Операторы преобразования помогают полностью интегрировать типы классов в среду программирования на СФ, разрешая свободно пользоваться классами вместе с другими типами данных, при условии, что определен порядок преобразования в эти типы.
Существуют две формы операторов преобразования: явная и неявная. Ниже они представлены в общем виде: рпЫгс ягагзс ехр1гсгг орегассг целевой тип(исходный тип у) (гегпгп значение; ) рпЫгс ягаггс 1ир11с1г орегасог целевой тип(исходный тип у) (гегпгп значение; ) где целевой тип обозначает тот тип, в который выполняется преобразование; ис— ходный тип — тот тип, который преобразуется; значение — конкретное значение, приобретаемое классом после преобразования. Операторы преобразования возвращают данные, имеющие целевой тип, причем указывать другие возвращаемые типы данных не разрешается.
Если оператор преобразования указан в неявной форме (1тр11с1С), то преобразование вызывается автоматически, например, в том случае, когда объект используется в выражении вместе со значением целевого типа. Если же оператор преобразования указан в явной форме (ехр11сйс), то преобразование вызывается в том случае, когда выполняется приведение типов.
Для одних и тех же исходных и целевых типов данных нельзя указывать оператор преобразования одновременно в явной и неявной форме. Создадим оператор преобразования специально для класса ТЬгееО, чтобы продемонстрировать его применение. Допустим, что требуется преобразовать объект типа ТЬгееО в целое значение, чтобы затем использовать его в целочисленном выражении. Такое преобразование требуется, в частности, для получения произведения всех трех координат объекта.
С этой целью мы воспользуемся следующей неявной формой оператора преобразования. рпы1с ясасгс 1ир11сгс орегасог гпг(тьгеео ор1) ( гегпгп ор1.х * ср1.у * ор1.г! ) Ниже приведен пример программы, демонстрирующей применение этого оператора преобразования. Пример применения оператора неявного преобразования.
пя1пд зуягеьи Класс для хранения трехмерных координат. с1аяя ТЬгеео ( 1пс х, у, г; // трехмерные координаты рпЬ11с ТЬгеео() ( х = у = г = О; ) рпЫгс Тдгеео(гпс г, гпс З, гпг Х) ( х = г; у = З; г = Гы ) Перегрузить бинарный оператор рпЫгс ягаг1с ТЬгеео орегагог +(Тдгеео ср1, Тдгеео ор2) ( 294 Часть!. Язык С№ ТЬгееО геви1Г = пен ТЬгееО() гези1с.х = ор1.х + ор2.х) геви1с.у = ор1.у ь ор2.ут гези1Г.г = ор1.г + ор2.г) гесигп геви1сг ) // Неявное преобразование объекта типа ТЬгееп к типу гпс. риЫгс асасгс 1жр11с1Г орегасог гпс(ТЬгеео ор1) ( гесигп ор1.х * ор1.у * ор1.г; ) // Вывести координаты Х, т, Е.
риЫРс ноуб НЬон() ( Сопао1е.Хгзсе).зпе (х + ", " т у + ", " т г); ) с1авв ТЬгееооеио ( вгаг1с ното Мази() ( ТЬгееО а = пен ТЬгееО(1, 2, 3) 1 ТЬгееО Ь = пен ТЬгееО(10, 10, 10) тьгееО с = пен ТЬгееО(); гпг 1; Сопво1е.нггсе("Координаты точки а: "); а.зьон(); Сопао1е.нг1сеьупе()г Сопао1е.иггсе("Координаты точки Ь: ")т Ь.НЬон() 1 Сопво1е.кг1сеь1пе()г с = а + Ь," // сложить координаты точек а и Ь Сопво1е.игссе("Результат сложения а + Ъ: "); с.Бпон()г Сопао1е.игусепупе(); — а1 // преобразовать в тип гпг Сопво1е.иггсеьгпе("Результат присваивания г = а: " + 1) Сопзо1е.нггсеьгпе()) = а * 2 — Ь) // преобразовать в тип Тпс Сопво1е.иггсевьпе("Результат вычисления выражения а * 2 — Ь: ) Вот к какому результату приводит выполнение этой программы.
координаты точки а: 1, 2, 3 Координаты точки Ь: 10, 10, 10 Глава 9. Перегрузка операторов 295 Результат сложения а + Ь: 11, 12, 13 Результат присваивания 1 = а: б Результат вычисления выражения а * 2 — Ь: -988 Как следует из приведенного выше примера программы, когда объект типа ТЬ гее О используется в таком целочисленном выражении, как 1 = а, происходит его преобразование. В этом конкретном случае преобразование приводит к возврату целого значения б, которое является произведением координат точки а, хранящихся в объекте того же названия.
Но если для вычисления выражения преобразование в тип Тпг не требуется, то оператор преобразования не вызывается. Именно поэтому операторный метод орегагог Тпс() не вызывается при вычислении выражения с = а + Ь. Но для различных целей можно создать разные операторы преобразования. Так, для преобразования объекта типа ТЬгееО в тип бопЫе можно было бы определить второй оператор преобразования.
При этом каждый вид преобразования выполнялся бы автоматически и независимо от другого. Оператор неявного преобразования применяется автоматически в следующих случаях: когда в выражении требуется преобразование типов; методу передается объект; осуществляется присваивание и производится явное приведение к целевому типу. С другой стороны, можно создать оператор явного преобразования, вызываемый только тогда, когда производится явное приведение типов. В таком случае оператор явного преобразования не вызывается автоматически.
В качестве примера ниже приведен вариант предыдущей программы, переделанный для демонстрации явного преобразования в тип Тпс. // Применить явное преобразование. пз1пч зузсеьы // Класс для хранения трехмерных координат. с1азз ТЬгееО ( Тпг х, у, г; // трехмерные координаты рпЫгс ТЬгеео() ( х = у = г = О; ) рпыгс тьгеео(гпг 1, ьпг 1, гпг ю ( х = 11 у = 91 г = кг ) // Перегрузить бинарный оператор рпЫ1с ягасгс ТЬгееО орегагпг +(ТЬгееО ор1, ТЬгееО ор2) ( ТЬгееО гезп1Г = пеи ТЬгееО(); гезп1Г.х = ор1.х + ор2.хг гезп1шу = ор1.у + ор2.уг гезп1Ыг ор1.г ь ор2.г; гетагп гезп1Ы ) // Выполнить на этот раз явное преобразование типов. рпЫгс зсатгс ехр11с1Г орегасог 1пс(ТЬгееО ор1) геспгп ор1.х * ор1.у * ор1.г; 296 Часть 1.