Г. Шилдт - Полный справочник по C# (1160789), страница 44
Текст из файла (страница 44)
И если бывыражение генерировало значение иного типа (а не типа ThreeD), такое составноевыражение попросту не работало бы.И еще один важный момент. При сложении координат внутри методаo p e r a t o r * () выполняется целочисленное сложение, поскольку отдельные координаты представляют собой целочисленные величины. Факт перегрузки оператора " + " дляобъектов типа ThreeD не влияет на оператор " + " , применяемый к целым числам.Теперь рассмотрим операторный метод o p e r a t o r - ( ) .
Оператор " - " работает подобно оператору " + " за исключением того, что здесь важен порядок следования операндов. Вспомните, что сложение коммутативно, а вычитание — нет (т.е. А—В не тоже самое, что В—А). Для всех бинарных операторов первый параметр операторногометода будет содержать левый операнд, а второй параметр — правый. При реализацииперегруженных версий некоммутативных операторов необходимо помнить, какойоперанд является левым, а какой — правым.Перегрузка унарных операторовУнарные операторы перегружаются точно так же, как и унарные. Главное отличие,конечно же, состоит в том, что в этом случае существует только один операнд.
Рассмотрим, например, метод, который перегружает унарный "минус" для классаThreeD.// Перегрузка унарного оператора "-".public static ThreeD operator -(ThreeD op)ThreeD result = new ThreeD();result.x = -op.x;result.у = -op.у;result.z = -op.z;return result;Здесь создается новый объект, который содержит поля операнда, но со знаком"минус".
Созданный таким образом объект и возвращается операторным методомo p e r a t o r - ( ) . Обратите внимание на то, что сам операнд остается немодифицированным. Такое поведение соответствует обычному действию унарного "минуса". Например, в выраженииа = -Ьа получает значение Ь, взятое с противоположным знаком, но само b при этом не меняется.228Часть I. Язык С#Однако в двух случаях операторный метод изменяет содержимое операнда. Речьидет об операторах инкремента (++) и декремента (—). Поскольку обычно ("в миру")эти операторы выполняют функции инкрементирования и декрементирования значений, соответственно, то перегруженные операторы " + " и " - " , как правило, инкрементируют свой операнд. Таким образом, при перегрузке этих операторов операнд обычно модифицируется.
Например, рассмотрим метод operator++ () для класса ThreeD.// Перегрузка унарного оператора "++".public s t a t i c ThreeD operator ++(ThreeD op)// Оператор "++" модифицирует аргумент.op.x++;op.y++;op.z++;return op;Обратите внимание: в результате выполнения этого операторного метода объект,на который ссылается операнд ор, модифицируется. Итак, операнд, подвергнутыйоперации "++", инкрементируется.
Более того, модифицированный объект возвращается этим методом, благодаря чему оператор "++" можно использовать в более сложных выражениях.Ниже приведена расширенная версия предыдущего примера программы, которая,помимо прочего, демонстрирует определение и использование унарных операторов " " и "++".// Перегрузка большего числа операторов.using System;// Класс трехмерных координат,class ThreeD {int х, у, 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;// Перегрузка бинарного оператора "-".public static ThreeD operator -(ThreeD opl, ThreeD op2)ThreeD result = new ThreeD();/* Обратите внимание на порядок операндов.Глава 9. Перегрузка операторов229- opl result.хresult.уresult.2левый операнд, ор2 - правый. */= opl.x - ор2.х;= opl.у - ор2.у;= opl.z - op2.z;return result;// Перегрузка унарного оператора "-".public static ThreeD operator -(ThreeD op){ThreeD result = new ThreeD();result.x = -op.x;result.у = -op.у;result.z = -op.z;return result;// Перегрузка унарного оператора "++".public static ThreeD operator ++(ThreeD op){// Оператор "++" модифицирует аргумент.op.x++;op.y++;op.z++;, return op;// Отображаем координаты 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 ThreeDdO, 10, 10);ThreeD с = new ThreeD();Console.Write("Координаты точки а: " ) ;a.show();Console.WriteLine() ;Console.Write("Координаты точки b: " ) ;b.show();Console.WriteLine();с = a + b; // Сложение а и b.Console.Write("Результат сложения а + b: " ) ;с.show();Console.Wri teLine() ;c = a + b + c;.// Сложение a, b и с.Console.Write("Результат сложения а + b + с: " ) ;230Часть I.
Язык С#с.show();Console.WriteLine() ;с = с - a; // Вычитание а из с.Console.Write("Результат вычитания с - а: " ) ;с.show();Console.WriteLine();с = с - b; // Вычитание b из с.Console.Write("Результат вычитания с - Ь: " ) ;с.show();Console.WriteLine() ;с = -а; // Присваивание -а объекту с.Console.Write("Результат присваивания -а: " ) ;с.show();Console.WriteLine();а++; // Инкрементирование а.Console.Write("Результат инкрементирования а++: ") ;а.show();Результаты выполнения этой программы выглядят так:Координаты точки а: 1, 2, 3Координаты точки Ь: 10, 10, 10Результат сложения а + Ь: 11, 12, 13Результат сложения а + Ь + с : 22, 24, 26Результат вычитания с - а: 21, 22, 23Результат вычитания с - Ь: 11, 12, 13Результат присваивания -а: -1, -2, -3ГРезультат инкрементирования а++: 2, 3, 4Как вы уже знаете, операторы "++" и " — " имеют как префиксную, так и постиксную форму.
Например, инструкциии8представляют собой допустимое использование оператора инкремента. Однако приперегрузке оператора " + + " обе формы вызывают один и тот же метод. Следовательно,в этом случае невозможно отличить префиксную форму оператора "++" от постфиксной. Это касается и перегрузки оператора " — " .Глава 9. Перегрузка операторов231i-J Выполнение операций над значениямивстроенных С#-типовДля любого заданного класса и оператора любой операторный метод сам можетперегружаться. Одна из самых распространенных причин этого — разрешить операции между объектами этого класса и другими (встроенными) типами данных. В качестве примера давайте снова возьмем класс ThreeD.
Вы видели, как перегрузить оператор " + " , чтобы он суммировал координаты одного ThreeD-объекта с координатамидругого. Однако это не единственный способ определения операции сложения длякласса ThreeD. Например, может потребоваться суммирование какого-либо целогочисла с каждой координатой ThreeD-объекта. Ведь тогда эту операцию можно использовать для смещения осей. Для ее реализации необходимо перегрузить оператор" + " еще раз, например, так:// Перегружаем бинарный оператор " + " для суммирования// объекта и int-значения.public s t a t i c ThreeD operator +(ThreeD opl, i n t op2)ThreeD r e s u l t = new ThreeD();r e s u l t .
x = opl.x + op2;r e s u l t . у = opl.у + op2;r e s u l t . z = opl.z + op2;return r e s u l t ;Обратите внимание на то, что второй параметр имеет тип i n t . Таким образом,этот метод позволяет сложить int-значение с каждым полем ThreeD-объекта. Этовполне допустимо, поскольку, как разъяснялось выше, при перегрузке бинарного оператора тип только одного из его операндов должен совпадать с типом класса, для которого перегружается этот оператор. Другой операнд может иметь любой тип.Ниже приведена версия класса ThreeD, которая имеет два перегруженных методаoperator+()./* Перегрузка оператора сложения для вариантов:объект + объект и объект + 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();/* Суммирование координат двух точеки возврат результата.
*/232Часть I. Язык С#r e s u l t . x = opl.x + op2.x;r e s u l t . у = opl.y + op2.y;r e s u l t . z = opl.z + op2.z;return r e s u l t ;// Перегружаем бинарный оператор "+" для варианта// "объект + int-значение".public static ThreeD operator +(ThreeD opl, int op2){ThreeD result = new ThreeD();result.x = opl.x + op2;r e s u l t . у = opl.y + op2;r e s u l t .