Г. Шилдт - Полный справочник по C# (1160789), страница 45
Текст из файла (страница 45)
z = opl.z + op2;return r e s u l t ;// Отображаем координаты X, Y, Z.public void show(){Console.WriteLine(x + ", " + у + ", " + z ) ;class ThreeDDemo {public static void Main() {ThreeD a = new ThreeD(1, 2, 3 ) ;ThreeD b = new ThreeD (10, 10, 10);ThreeD с = new ThreeD();Console.Write("Координаты точки а: " ) ;a.show();Console.WriteLine();Console.Write("Координаты точки b: " ) ;b.show();Console.WriteLine();с = a + b; // объект + объектConsole.Write("Результат сложения а + b: " ) ;с.show();Console.WriteLine();с = b + 10; // объект + int-значениеConsole.Write("Результат сложения b + 10:с.show();" ) ;При выполнении программа генерирует следующие результаты:Координаты точки а: 1, 2, 3Координаты точки Ь: 10, 10, 10Результат сложения а + Ь: 11, 12, 13Результат сложения b + 10: 20, 20, 20Глава 9. Перегрузка операторов233Как подтверждают результаты выполнения этой программы, если оператор " + "применяется к двум объектам, их соответствующие координаты суммируются.
А еслиоператор " + " применяется к объекту и целому числу, то значения координат объектаувеличиваются на это целое число.Несмотря на то что приведенный выше способ перегрузки оператора " + " существенным образом расширяет возможности класса ThreeD, работа на этом еще не окончена. И вот почему. Метод o p e r a t o r * (ThreeD, i n t ) позволяет выполнять инструкции, подобные следующей.I obi = оЬ2 + 10;Но, к сожалению, он не позволяет выполнять инструкции такого рода:obi = 10 + оЬ2;Дело в том, что целочисленное значение принимается в качестве второго аргумента, которым является правый операнд. А в предыдущей инструкции целочисленныйаргумент находится слева.
Чтобы сделать допустимыми две формы инструкций, необходимо перегрузить оператор " + " еще раз. Новая версия должна будет в качестве первого параметра принимать значение типа i n t , а в качестве второго — объект типаThreeD. И тогда старая версия метода o p e r a t o r + ( ) будет обрабатывать вариант"объект •+• i n t -значение", а новая — вариант " i n t - значение + объект". Перегрузка оператора " + " (или любого другого бинарного оператора), выполненная подобнымобразом, позволит значению встроенного типа находиться слева или справа от оператора. Ниже приводится версия класса ThreeD, которая перегружает оператор " + " сучетом описанных выше вариантов приема аргументов./* Перегрузка оператора "+" для следующих вариантов:объект + объект,объект + int-значение иint-значение + объект. */using System;// Класс трехмерных координат,class ThreeD {int x, у, z; // 3-х-мерные координаты.public ThreeD() { х = у = z = 0; }public ThreeD(int i, int j, int k) {x = i; у = j; z = k; }// Перегружаем бинарный оператор "+" для варианта// "объект + объект".public static ThreeD operator +(ThreeD opl, ThreeD op2){ThreeD result = new ThreeD();/*Суммирование координат двух точеки возврат результата.
*/result.х = opl.x + ор2.х;result.у = opl.у + ор2.у;result.z = opl.z + op2.z;return result;}// Перегружаем бинарный оператор "+" для варианта// "объект + int-значение".234Часть I. Язык С#public static ThreeD operator +(ThreeD opl f int op2){ThreeD result = new ThreeD();result.x = opl.x + op2;result.у = opl.y + op2;result.z = opl.z + op2;return result;// Перегружаем бинарный оператор "+" для варианта// "int-значение + объект".public static ThreeD operator +(int opl, ThreeD op2){ThreeD result = new ThreeD();result.x = op2.x + opl;result.у = op2.y + opl;result.z = op2.z + opl;return result;// Отображаем координаты X, Y, Z.public void show(){Console.WriteLine(x + ", " + у + ", " + z ) ;class ThreeDDemo {public static void Main() {ThreeD a = new ThreeD(1, 2, 3) ;ThreeD b = new ThreeD(10, 10, 10);ThreeD с = new ThreeD();Console.Write("Координаты точки а: " ) ;a.show();Console.WriteLine() ;Console.Write("Координаты точки b: " ) ;b.show();Console.WriteLine();с = a + b; // объект + объектConsole.Write("Результат сложения a + b: " ) ;c.show();Console.WriteLine() ;с = b + 10; // объект + int-значениеConsole.Write("Результат сложения b + 10: " ) ;с.show();Console.WriteLine() ;с = 15 + b; // int-значение + объектConsole.Write("Результат сложения 15 + b: " ) ;с.show();Глава 9.
Перегрузка операторов235Вот результаты выполнения этой программы:Координаты точки а: 1, 2, 3Координаты точки Ь: 10, 10, 10Результат сложения а + Ь: 11, 12, 13Результат сложения b + 10: 20, 20, 20Результат сложения 15 + Ь: 25, 25, 25111 Перегрузка операторов отношенийОператоры отношений (например, "==" или "<") также можно перегружать, причем сделать это совсем нетрудно. Как правило, перегруженный оператор отношениявозвращает одно из двух возможных значений: t r u e или f a l s e .
Это позволяет использовать перегруженные операторы отношений в условных выражениях. Если бы они возвращали результат другого типа, это бы весьма ограничило круг их применения.Рассмотрим версию класса ThreeD, который перегружает операторы "<" и ">".// Перегрузка операторов "<" и ">".using System;// Класс трехмерных координат,class ThreeD {int x, у, z; // 3-х-мерные координаты.public ThreeD () { х = у = z = 0; }public ThreeD(int i, int j , int k) {x = i;у = j ; z = k;}// Перегрузка оператора "<".public static bool operator <(ThreeD opl, ThreeD op2){if((opl.x < op2.x) && (opl.у < op2.y) &&(opl.z < op2.z))return true;elsereturn false;}// Перегрузка оператора ">".public static bool operator >(ThreeD opl, ThreeD op2){if((opl.x > op2.x) && (opl.у > op2.y) &&(opl.z > op2.z))return true;elsereturn false;}// Отображаем координаты X, Y, Z.public void show()236Часть I.
Язык С#Console.WriteLine(x + ", " + у + ", " + z ) ;class ThreeDDemo {public static void Main() {ThreeD a = new ThreeD(5, 6, 7 ) ;ThreeD b = new ThreeD(10, 10, 10);ThreeD с = new ThreeD(1, 2, 3 ) ;Console.Write("Координаты точки а: " ) ;a.show();Console.Write("Координаты точки b: " ) ;b.show();Console.Write("Координаты точки с: " ) ;с.show();Console.WriteLine() ;if(aif(aif(aif(a><><c)c)b)b)Console.WriteLine("a >Console.WriteLine("a <Console.WriteLine("a >Console.WriteLine("a <ссbb- ИСТИНА")- ИСТИНА")- ИСТИНА")- ИСТИНА")При выполнении эта программа генерирует такие результаты:Координаты точки а: 5, 6, 7Координаты точки Ь: 10, 10, 10Координаты точки с: 1, 2, 3а > с - ИСТИНАа < b - ИСТИНАНа перегрузку операторов отношений налагается серьезное ограничение: их следует перегружать парами.
Например, перегружая оператор "<", вы также должны перегрузить оператор ">", и наоборот. Вот что подразумевается под парами операторовотношений:Перегружая операторы "==" и " ! = " , следует перегрузить также методыObject.Equals () и Object.GetHashCode (). Эти методы (а также их перегрузка)рассматриваются в главе 11.Перегрузка операторов t r u e и f a l s eКлючевые слова t r u e и f a l s e в целях перегрузки также можно использовать в качестве унарных операторов. Перегруженные версии этих операторов обеспечиваютспецифическое определение понятий ИСТИНА и ЛОЖЬ в отношении создаваемыхпрограммистом классов. Если для класса реализовать таким образом ключевые словаt r u e и f a l s e , то затем объекты этого класса можно использовать для управления инструкциями if, while, for и do-while, а также в ?-выражении.
Их можно даже использовать для реализации специальных типов логики (например, нечеткой логики).Глава 9. Перегрузка операторов237Операторы t r u e и f a l s e должны быть перегружены в паре. Нельзя перегружатьтолько один из них. Оба они выполняют функцию унарных операторов и имеют такой формат:p u b l i c s t a t i c bool o p e r a t o r true{тип_параметра op){I/ Возврат значения true или f a l s e .}public s t a t i c bool operator false{тип_параметраop){//Возврат значения true илиfalse.}Обратите внимание на то, что каждая форма возвращает результат типа bool.В следующем примере демонстрируется один из возможных способов реализацииоператоров t r u e и f a l s e для класса ThreeD. Предполагается, что ThreeD-объект истинен, если по крайней мере одна его координата не равна нулю.
Если все три координаты равны нулю, объект считается ложным. В целях демонстрации здесь такжееализован оператор декремента.// Перегрузка операторов t r u e и f a l s e для класса ThreeD.using System;// Класс трехмерных координат,class ThreeD {int x, у, z; // 3-х-мерные координаты.public ThreeD() { х = у = z = 0; }public ThreeD(int i , i n t j , i n t k) {x = i;у = j ; z = k; }// Перегружаем оператор true.public static bool operator true(ThreeD op) {if((op.x != 0) M (op.у != 0) || (op.z != 0))return true; // Хотя бы одна координата не равна 0.elsereturn false;}// Перегружаем оператор false.public static bool operator false(ThreeD op) {if((op.x == 0) && (op.у == 0) && (op.z == 0))return true; // Все координаты равны нулю,elsereturn false;// Перегружаем унарный оператор хх — " .public static ThreeD operator —(ThreeD op)op.x—;op.y—;op.z—;return op;// Отображаем координаты X, Y, Z.238Часть I.
Язык С #public void show(){Console.WriteLine(x + ", " + у + ", " + z) ;class TrueFalseDemo {public static void Main() {ThreeD a = new ThreeD(5, 6, 7 ) ;ThreeD b = new ThreeD(10, 10, 10);ThreeD с = new ThreeD(0, 0, 0 ) ;Console.Write("Координаты точки а: " ) ;a. show() ;Console.Write("Координаты точки b: " ) ;b.show();Console.Write("Координаты точки с: " ) ;с.show();Console.WriteLine() ;if(a) Console.WriteLine("a - это ИСТИНА.");else Console.WriteLine("a - это ЛОЖЬ.");if(b) Console.WriteLine("b - это ИСТИНА.");else Console.WriteLine("b - это ЛОЖЬ.");if(с) Console.WriteLine("с - это ИСТИНА.");else Console.WriteLine("с - это ЛОЖЬ.");Console.WriteLine();Console.WriteLine("Управляем циклом, используя объект класса ThreeD.")do {b.show();b—;} while(b);Вот какие результаты генерирует эта программа:Координаты точки а: 5, 6, 1Координаты точки Ь: 10, 10, 10Координаты точки с: 0, 0, 0а - это ИСТИНА,b - это ИСТИНА,с - это ЛОЖЬ.Управляем циклом, используя объект класса ThreeD.10, 10, 109, 9, 98, 8, 87, 7, 76, б, б5, 5, 54, 4, 43, 3, 32, 2, 2Глава 9.
Перегрузка операторов239Обратите внимание на то, что объекты класса ThreeD используются для управления if-инструкциями и while-цикла. Что касается if-инструкций, то ThreeD-объектоценивается с помощью ключевого слова t r u e . В случае истинности результата этойоперации выполняется соответствующая инструкция. В случае do-while-цикла каждая его итерация декрементирует значение объект Ь. Цикл выполняется до тех пор,пока значение объекта b оценивается как ИСТИНА (т.е.
содержит по крайней мереодну ненулевую координату). Когда все координаты объекта b станут равными нулю,он (объект) будет считаться ложным (благодаря оператору t r u e ) , и цикл прекратится.Перегрузка логических операторовКак вы знаете, в С# определены следующие логические операторы: &, | , !, && и| |. Безусловно, перегруженными могут быть только &, | , !.