1629295407-c61bfe4caba98380ea3e7cdae6295416 (846200), страница 44
Текст из файла (страница 44)
*/232Часть I. Язык C#result.x = op1.x + op2.x;result.y = op1.y + op2.y;result.z = op1.z + op2.z;return result;}}// Перегружаем бинарный оператор "+" для варианта// "объект + int-значение".public static ThreeD operator +(ThreeD op1, int op2) {ThreeD result = new ThreeD();result.x = op1.x + op2;result.y = op1.y + op2;result.z = op1.z + op2;return result;}// Отображаем координаты X, Y, Z.public void show() {Console.WriteLine(x + ", " + y + ", " + z);}class ThreeDDemo {public static void Main() {ThreeD a = new ThreeD(1, 2, 3);ThreeD b = new ThreeD(10, 10, 10);ThreeD c = new ThreeD();Console.Write("Координаты точки a: ");a.show();Console.WriteLine();Console.Write("Координаты точки b: ");b.show();Console.WriteLine();c = a + b; // объект + объектConsole.Write("Результат сложения а + b: ");c.show();Console.WriteLine();}}c = b + 10; // объект + int-значениеConsole.Write("Результат сложения b + 10: ");c.show();При выполнении программа генерирует следующие результаты:Координаты точки a: 1, 2, 3Координаты точки b: 10, 10, 10Результат сложения а + b: 11, 12, 13Результат сложения b + 10: 20, 20, 20Глава 9.
Перегрузка операторов233Как подтверждают результаты выполнения этой программы, если оператор “+”применяется к двум объектам, их соответствующие координаты суммируются. А еслиоператор “+” применяется к объекту и целому числу, то значения координат объектаувеличиваются на это целое число.Несмотря на то что приведенный выше способ перегрузки оператора “+”существенным образом расширяет возможности класса ThreeD, работа на этом еще неокончена. И вот почему. Метод operator+(ThreeD, int) позволяет выполнятьинструкции, подобные следующей.оb1 = оb2 + 10;Но, к сожалению, он не позволяет выполнять инструкции такого рода:оb1 = 10 + оb2;Дело в том, что целочисленное значение принимается в качестве второго аргумента,которым является правый операнд.
А в предыдущей инструкции целочисленный аргументнаходится слева. Чтобы сделать допустимыми две формы инструкций, необходимоперегрузить оператор “+” еще раз. Новая версия должна будет в качестве первогопараметра принимать значение типа int, а в качестве второго — объект типа ThreeD. Итогда старая версия метода operator+() будет обрабатывать вариант “объект + intзначение”, а новая — вариант “int-значение + объект”. Перегрузка оператора “+”(или любого другого бинарного оператора), выполненная подобным образом, позволитзначению встроенного типа находиться слева или справа от оператора. Ниже приводитсяверсия класса ThreeD, которая перегружает оператор “+” с учетом описанных вышевариантов приема аргументов./* Перегрузка оператора "+" для следующих вариантов:объект + объект,объект + int-значение иint-значение + объект.
*/using System;// Класс трехмерных координат.class ThreeD {int x, y, z; // 3-х-мерные координаты.public ThreeD() {x = y = z = 0;}public ThreeD(int i, int j, int k) {x = i;y = j;z = k;}// Перегружаем бинарный оператор "+" для варианта// "объект + объект".public static ThreeD operator +(ThreeD op1, ThreeD op2){ThreeD result = new ThreeD();/* Суммирование координат двух точеки возврат результата.
*/result.x = op1.x + op2.x;result.y = op1.y + op2.y;result.z = op1.z + op2.z;return result;}// Перегружаем бинарный оператор "+" для варианта// "объект + int-значение".234Часть I. Язык C#public static ThreeD operator +(ThreeD op1, int op2) {ThreeD result = new ThreeD();result.x = op1.x + op2;result.y = op1.y + op2;result.z = op1.z + op2;return result;}// Перегружаем бинарный оператор "+" для варианта// "int-значение + объект".public static ThreeD operator +(int op1, ThreeD op2) {ThreeD result = new ThreeD();result.x = op2.x + op1;result.y = op2.y + op1;result.z = op2.z + op1;return result;}// Отображаем координаты X, Y, Z.public void show() {Console.WriteLine(x + ", " + y + ", " + z);}}class ThreeDDemo {public static void Main() {ThreeD a = new ThreeD(1, 2, 3);ThreeD b = new ThreeD(10, 10, 10);ThreeD c = new ThreeD();Console.Write("Координаты точки a: ");a.show();Console.WriteLine();Console.Write("Координаты точки b: ");b.show();Console.WriteLine();c = a + b; // объект + объектConsole.Write("Результат сложения а + b: ");c.show();Console.WriteLine();c = b + 10; // объект + int-значениеConsole.Write("Результат сложения b + 10: ");c.show();Console.WriteLine();}}c = 15 + b; // int-значение + объектConsole.Write("Результат сложения 15 + b: ");c.show();Глава 9.
Перегрузка операторов235Вот результаты выполнения этой программы:Координаты точки a: 1, 2, 3Координаты точки b: 10, 10, 10Результат сложения а + b: 11, 12, 13Результат сложения b + 10: 20, 20, 20Результат сложения 15 + b: 25, 25, 25Перегрузка операторов отношенийОператоры отношений (например, “==” или “<”) также можно перегружать, причемсделать это совсем нетрудно. Как правило, перегруженный оператор отношения возвращаетодно из двух возможных значений: true или false.
Это позволяет использоватьперегруженные операторы отношений в условных выражениях. Если бы они возвращалирезультат другого типа, это бы весьма ограничило круг их применения. Рассмотрим версиюкласса ThreeD, который перегружает операторы “<” и “>”.// Перегрузка операторов "<" и ">".using System;// Класс трехмерных координат.class ThreeD {int x, y, z; // 3-х-мерные координаты.public ThreeD() {x = y = z = 0;}public ThreeD(int i, int j, int k) {x = i;y = j;z = k;}// Перегрузка оператора "<".public static bool operator <(ThreeD op1, ThreeD op2){if((op1.x < op2.x) && (op1.y < op2.y) &&(op1.z < op2.z))return true;elsereturn false;}// Перегрузка оператора ">".public static bool operator >(ThreeD op1, ThreeD op2){if((op1.x > op2.x) && (op1.y > op2.y) &&(op1.z > op2.z))return true;elsereturn false;}// Отображаем координаты X, Y, Z.public void show(){236Часть I.
Язык C#}}Console.WriteLine(x + ", " + y + ", " + z);class ThreeDDemo {public static void Main() {ThreeD a = new ThreeD(5, 6, 7);ThreeD b = new ThreeD(10, 10, 10);ThreeD c = new ThreeD(1, 2, 3);Console.Write("Координаты точки a: ");a.show();Console.Write("Координаты точки b: ");b.show();Console.Write("Координаты точки c: ");c.show();Console.WriteLine();}}if(aif(aif(aif(a><><c)c)b)b)Console.WriteLine("aConsole.WriteLine("aConsole.WriteLine("aConsole.WriteLine("a><><ccbb-ИСТИНА");ИСТИНА");ИСТИНА");ИСТИНА");При выполнении эта программа генерирует такие результаты:Координаты точки a: 5, б, 7Координаты точки b: 10, 10, 10Координаты точки c: 1, 2, 3а > c - ИСТИНА а < b - ИСТИНАНа перегрузку операторов отношений налагается серьезное ограничение: их следуетперегружать парами. Например, перегружая оператор “<”, вы также должны перегрузитьоператор “>”, и наоборот.
Вот что подразумевается под парами операторов отношений:==!=<><=>=Перегружая операторы “==” и “!=”, следует перегрузить также методыObject.Equals() и Object.GetHashCode(). Эти методы (а также их перегрузка)рассматриваются в главе 11.Перегрузка операторов true и falseКлючевые слова true и false в целях перегрузки также можно использовать вкачестве унарных операторов. Перегруженные версии этих операторов обеспечиваютспецифическое определение понятий ИСТИНА и ЛОЖЬ в отношении создаваемыхпрограммистом классов. Если для класса реализовать таким образом ключевые слова trueи false, то затем объекты этого класса можно использовать для управления инструкциямиif, while, for и do-while, а также в ?-выражении.
Их можно даже использовать дляреализации специальных типов логики (например, нечеткой логики).Глава 9. Перегрузка операторов237Операторы true и false должны быть перегружены в паре. Нельзя перегружатьтолько один из них. Оба они выполняют функцию унарных операторов и имеют такойформат:public static bool operator true(тип_параметра op){// Возврат значения true или false.}public static bool operator false(тип_параметра op) {// Возврат значения true или false.}Обратите внимание на то, что каждая форма возвращает результат типа bool.В следующем примере демонстрируется один из возможных способов реализацииоператоров true и false для класса ThreeD. Предполагается, что ThreeD-объектистинен, если по крайней мере одна его координата не равна нулю.
Если все трикоординаты равны нулю, объект считается ложным. В целях демонстрации здесь такжереализован оператор декремента.// Перегрузка операторов true и false для класса ThreeD.using System;// Класс трехмерных координат.class ThreeD {int x, y, z; // 3-х-мерные координаты.public ThreeD() {x = y = z = 0;}public ThreeD(int i, int j, int k) {x = i;y = j;z = k;}// Перегружаем оператор true.public static bool operator true(ThreeD op) {if((op.x !=0) || (op.y != 0) || (op.z != 0))return true; // Хотя бы одна координата не равна 0.elsereturn false;}// Перегружаем оператор false.public static bool operator false(ThreeD op) {if((op.x == 0) && (op.y == 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.
Язык C#public void show() {Console.WriteLine(x + ", " + y + ", " + z);}}class TrueFalseDemo {public static void Main() {ThreeD a = new ThreeD(5, 6, 7);ThreeD b = new ThreeD(10, 10, 10);ThreeD c = new ThreeD(0, 0, 0);Console.Write("Координаты точки a: ");a.show();Console.Write("Координаты точки b: ");b.show();Console.Write("Координаты точки c: ");c.show();Console.WriteLine();}}if(a) Console.WriteLine("a - это ИСТИНА.");else Console.WriteLine("a - это ЛОЖЬ.");if(b) Console.WriteLine("b - это ИСТИНА.");else Console.WriteLine("b - это ЛОЖЬ.");if(c) Console.WriteLine("с - это ИСТИНА.");else Console.WriteLine("с - это ЛОЖЬ.");Console.WriteLine();Console.WriteLine("Управляем циклом, используя объект класса ThreeD.");do {b.show();b--;} while(b);Вот какие результаты генерирует эта программа:Координаты точки a: 5, 6, 7Координаты точки b: 10, 10, 10Координаты точки c: 0, 0, 0а - это ИСТИНА.b - это ИСТИНА.c - ЭТО ЛОЖЬ.Управляем циклом, используя объект класса ThreeD.10, 10, 109, 9, 98, 8, 87, 7, 76, 6, 65, 5, 54, 4, 43, 3, 32, 2, 21, 1, 1Глава 9.