Полное руководство. С# 4.0 - Шилдт Герберт
Шрифт:
Интервал:
Закладка:
А теперь проанализируем операторный метод operator-(). Оператор - действует так же, как и оператор +, но для него важен порядок следования операндов. Напомним, что сложение носит коммутативный характер (от перестановки слагаемых суммане меняется), чего нельзя сказать о вычитании: А - В не то же самое, что и В - А! Длявсех двоичных операторов первым параметром операторного метода является левыйоперанд, а вторым параметром — правый операнд. Поэтому, реализуя перегружаемые варианты некоммутативных операторов, следует помнить, какой именно операнддолжен быть указан слева и какой — справа.Перегрузка унарных операторов
Унарные операторы перегружаются таким же образом, как и бинарные. Главноеотличие заключается, конечно, в том, что у них имеется лишь один операнд. В качестве примера ниже приведен метод, перегружающий оператор унарного минуса длякласса ThreeD.// Перегрузить оператор унарного минуса.public static ThreeD operator - (ThreeD op){ ThreeD result = new ThreeD (); result.x = -op.x; result.у = -op.у; result.z = -op.z; return result;}
В данном примере создается новый объект, в полях которого сохраняются отрицательные значения операнда перегружаемого унарного оператора, после чего этот объект возвращается операторным методом. Обратите внимание на то, что сам операнд неменяется. Это означает, что и в данном случае обычное назначение оператора унарногоминуса сохраняется. Например, результатом выраженияа = -b
является отрицательное значение операнда b, но сам операнд b не меняется.В C# перегрузка операторов ++ и -- осуществляется довольно просто. Для этогодостаточно возвратить инкрементированное или декрементированное значение, но неизменять вызывающий объект. А все остальное возьмет на себя компилятор С#, различая префиксные и постфиксные формы этих операторов. В качестве примера нижеприведен операторный метод operator++() для класса ThreeD.// Перегрузить унарный оператор ++.public static ThreeD operator ++(ThreeD op){ ThreeD result = new ThreeD(); // Возвратить результат инкрементирования. result.x = op.x + 1; result.у = op.у + 1; result.z = op.z + 1; return result;}
Ниже приведен расширенный вариант предыдущего примера программы, в котором демонстрируется перегрузка унарных операторов - и ++.// Пример перегрузки бинарных и унарных операторов.using System;// Класс для хранения трехмерных координат.class ThreeD { int х, у, z; // трехмерные координаты public ThreeD() { х = у = z = 0; } public ThreeD(int i, int j, int k) { x = i; у = j; z = k; } // Перегрузить бинарный оператор +. public static ThreeD operator +(ThreeD op1, ThreeD op2) { ThreeD result = new ThreeD(); /* Сложить координаты двух точек и возвратить результат. */ result.х = op1.x + ор2.х; result.у = op1.y + ор2.у; result.z = op1.z + op2.z; return result; } // Перегрузить бинарный оператор -. public static ThreeD operator -(ThreeD op1, ThreeD op2) { ThreeD result = new ThreeD(); /* Обратить внимание на порядок следования операндов: op1 — левый операнд, ор2 — правый операнд. */ result.х = op1.x - ор2.х; result.у = op1.y - ор2.у; result.z = op1.z - op2.z; return result; } // Перегрузить унарный оператор -. public static ThreeD operator -(ThreeD op) { ThreeD result = new ThreeD(); result.x = -op.x; result.у = -op.y; result.z = -op.z; return result; } // Перегрузить унарный оператор ++. public static ThreeD operator ++(ThreeD op) { ThreeD result = new ThreeD(); // Возвратить результат инкрементирования. result.x = op.x + 1; result.у = op.y + 1; result.z = op.z + 1; return result; } // Вывести координаты X, Y, Z. public void Show() { Console.WriteLine(x + ", " + у + ", " + z); }}class ThreeDDemo { static void Main() { ThreeD a = new ThreeD(1, 2, 3); ThreeD b = new ThreeD(10, 10, 10); ThreeD с = new ThreeD(); Console.Write("Координаты точки a: "); a.Show(); Console.WriteLine(); Console.Write("Координаты точки b: "); b.Show(); Console.WriteLine(); с = a + b; // сложить координаты точек а и b Console.Write("Результат сложения a + b: "); c.Show(); Console.WriteLine(); c = a + b + c; // сложить координаты точек a, b и с Console.Write("Результат сложения a + b + с: "); с.Show(); Console.WriteLine(); с = с - а; // вычесть координаты точки а Console.Write("Результат вычитания с - а: "); с.Show(); Console.WriteLine(); с = с - b; // вычесть координаты точки b Console.Write("Результат вычитания с - b: "); с.Show(); Console.WriteLine(); с = -a; // присвоить точке с отрицательные координаты точки а Console.Write("Результат присваивания -а: "); с.Show(); Console.WriteLine(); с = а++; // присвоить точке с координаты точки а, // а затем инкрементировать их Console.WriteLine("Если с = а++"); Console.Write("то координаты точки с равны "); с.Show(); Console.Write("а координаты точки а равны "); а.Show(); // Установить исходные координаты (1,2,3) точки а а = new ThreeD(1, 2, 3); Console.Write("nУстановка исходных координат точки а: "); а.Show(); с = ++а; // инкрементировать координаты точки а, // а затем присвоить их точке с Console.WriteLine("nЕсли с = ++а"); Console.Write("то координаты точки с равны "); с.Show(); Console.Write("а координаты точки а равны "); а.Show(); }}Вот к какому результату приводит выполнение данной программы.
Координаты точки а: 1, 2, 3Координаты точки b: 10, 10, 10Результат сложения а + b: 11, 12, 13Результат сложения а + b + с: 22, 24, 26Результат вычитания с - а: 21, 22, 23Результат вычитания с - b: 11, 12, 13Результат присваивания -а: -1, -2, -3Если с = а++то координаты точки с равны 1, 2, 3а координаты точки а равны 2, 3, 4Установка исходных координат точки а: 1, 2, 3Если с = ++ато координаты точки с равны 2, 3, 4а координаты точки а равны 2, 3, 4## Выполнение операций со встроенными в C# типами данныхДля любого заданного класса и оператора имеется также возможность перегрузитьсам операторный метод. Это, в частности, требуется для того, чтобы разрешить операции с типом класса и другими типами данных, в том числе и встроенными. Вновь обратимся к классу ThreeD. На примере этого класса ранее было показано, как оператор+ перегружается для сложения координат одного объекта типа ThreeD с координатами другого. Но это далеко не единственный способ определения операции сложениядля класса ThreeD. Так, было бы не менее полезно прибавить целое значение к каждойкоординате объекта типа ThreeD. Подобная операция пригодилась бы для переносаосей координат. Но для ее выполнения придется перегрузить оператор + еще раз, какпоказано ниже.
// Перегрузить бинарный оператор + для сложения объекта// типа ThreeD и целого значения типа int.public static ThreeD operator +(ThreeD op1, int op2){ ThreeD result = new ThreeD(); result.x = op1.x + op2; result.у = op1.y + op2; result.z = op1.z + op2; return result;}Как видите, второй параметр операторного метода имеет тип int. Следовательно,в этом методе разрешается сложение целого значения с каждым полем объекта типаThreeD. Такая операция вполне допустима, потому что, как пояснялось выше, приперегрузке бинарного оператора один из его операндов должен быть того же типа,что и класс, для которого этот оператор перегружается. Но у второго операнда этогооператора может быть любой другой тип.Ниже приведен вариант класса ThreeD с двумя перегружаемыми методами оператора +.
// Перегрузить бинарный оператор + дважды:// один раз - для сложения объектов класса ThreeD,// а другой раз — для сложения объекта типа ThreeD и целого значения типа int.using System;
// Класс для хранения трехмерных координат.class ThreeD { int х, у, z; // трехмерные координаты public ThreeD() { x = у = z = 0; } public ThreeD(int i, int j, int k) { x = i; у = j; z = k; } // Перегрузить бинарный оператор + для сложения объектов класса ThreeD. public static ThreeD operator + (ThreeD op1, ThreeD op2) { ThreeD result = new ThreeD(); / Сложить координаты двух точек и возвратить результат. / result.х = op1.x + ор2.х; result.у = op1.у + ор2.у; result.z = op1.z + op2.z; return result; } // Перегрузить бинарный оператор + для сложения // объекта типа ThreeD и целого значения типа int. public static ThreeD operator +(ThreeD opl, int op2) { ThreeD result = new ThreeD(); result.x = op1.x + op2; result.у = op1.у + op2; result.z = op1.z + op2; return result; } // Вывести координаты X, Y, Z. public void Show() { Console.WriteLine(x + ", " + у + ", " + z); }}