Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ответы по Технологии программирования / Прегрузка операторов (Унарных и бинарных)

.docx
Скачиваний:
7
Добавлен:
21.05.2015
Размер:
9.93 Кб
Скачать

4.3.1 Перегрузка бинарных операторов

В следующей программе создаётся класс ThreeD поддержки координат объекта в трехмерном пространстве.

Перегруженный оператор "+" выполняет сложение отдельных координат двух ThreeD-объектов, а перегруженный оператор "-" вычитает координаты одного ThreeD-объекта из координат другого.

// Пример перегрузки операторов.

usingSystem;

// Класс трехмерных координат,

classThreeD {

int x, у, z; // 3-х-мерные координаты.

publicThreeD () { x = у = z = 0; }

publicThreeD(int i, int j, int k) {

x = i; у = j;z=k;}

// Перегрузка бинарного оператора "+".

public static ThreeD operator +(ThreeD opl,ThreeD op2)

{

ThreeD result = newThreeD();

/* Суммирование координат двух точек

и возврат результата. */

result.x = opl.x + op2.x; // Эти операторы выполняют

result.у = opl.у + ор2.у; // целочисленное сложение,

result.z = opl.z + op2.z;

return result;

}

// Перегрузка бинарного оператора "-".

public static ThreeD operator -(ThreeD opl, ThreeD op2)

{

ThreeD result = new ThreeD();

/* Обратите внимание на порядок операндов.

opl - левый операнд, ор2 - правый. */

result.х = opl.x - ор2.х; // Эти операторы выполняют

result.у = opl.у - ор2.у; // целочисленное вычитание,

result.z = opl.z - op2.z;

return result;

}

// Отображаем координаты X, Y, Z.

public void show()

{

Console.WriteLine(x + ", " + у + ", " + z) ;

}}

classThreeDDemo {

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; // Складываем а и b.

Console.Write("Результат сложения а + b: " ) ;

с.show();

Console.WriteLine();

c = a + b + c ; // Складываем a, b и с.

Console.Write("Результат сложения а + b + с: " ) ;

с.show();

Console.WriteLine();

с = с - a; // Вычитаем а из с.

Console.Write("Результат вычитания с - а: " ) ;

с.show();

Console.WriteLine();

с = с - b; // Вычитаем b из с.

Console.Write("Результат вычитания с - b: " ) ;

с.show();

Console.WriteLine();

}}

При выполнении эта программа генерирует следующие результаты:

Координаты точки а: 1, 2, 3

Координаты точки b: 10, 10, 10

Результат сложения а + b: 11, 12, 13

Результат сложения а + b + с : 22, 24, 26

Результат вычитания с - а: 21, 22, 23

Результат вычитания с - b : 11, 12, 13

При воздействии оператора " + " на два объекта типа ThreeD величины соответствующих координат суммируются, как показано в методе operator+(). Однако заметьте, что этот метод не модифицирует значения ни одного из операндов. Этот метод возвращает новый объект типа ThreeD, который содержит результат выполнения рассматриваемой операции. Это происходит и в случае стандартного арифметического оператора сложения "+", примененного, например, к числам 10 и 12. Результат операции 10+12 равен 22, но при его получении ни 10, ни 12 не были изменены. Хотя не существует правила, которое бы не позволяло перегруженному оператору изменять значение одного из его операндов, все же лучше, чтобы он не противоречил общепринятым нормам. Обратите внимание на то, что метод operator+() возвращает объект типа ThreeD.

Несмотря на то что он мог бы возвращать значение любого допустимого в С# типа, тот факт, что он возвращает объект типа ThreeD, позволяет использовать оператор "+" в таких составных выражениях, как а+b Здесь часть этого выражения, а+b, генерирует результат типа ThreeD, который затем суммируется с объектом с. И если бы выражение генерировало значение иного типа (а не типа ThreeD), такое составное выражение попросту не работало бы. При сложении координат внутри метода operator+() выполняется целочисленное сложение, поскольку отдельные координаты представляют собой целочисленные величины. Факт перегрузки оператора "+" для объектов типа ThreeD не влияет на оператор "+", применяемый к целым числам.

Теперь рассмотрим операторный метод operator-(). Оператор "-" работает подобно оператору "+" за исключением того, что здесь важен порядок следования операндов. Вспомните, что сложение коммутативно, а вычитание — нет (т.е. А—В не то же самое, что В—А). Для всех бинарных операторов первый параметр операторного метода будет содержать левый операнд, а второй параметр — правый. При реализации перегруженных версий некоммутативных операторов необходимо помнить, какой операнд является левым, а какой — правым.

4.3.2 Перегрузка унарных операторов

Унарные операторы перегружаются точно так же, как и бинарные. Главное отличие, конечно же, состоит в том, что в этом случае существует только один операнд. Рассмотрим, например, метод, который перегружает унарный "минус" для класса ThreeD.

// Перегрузкаунарногооператора "-".

public static ThreeD operator -(ThreeD op)

{ThreeD result = new ThreeD();

result.x = -op.x;

result.у = -op.у;

result.z = -op.z;

return result;}

Здесь создается новый объект, который содержит поля операнда, но со знаком "минус". Созданный таким образом объект и возвращается операторным методом operator-(). Обратите внимание на то, что сам операнд остается не модифицированным. Такое поведение соответствует обычному действию унарного "минуса". Например, в выражении

а = -b

а получает значение b, взятое с противоположным знаком, но само b при этом не меняется.

Однако в двух случаях операторный метод изменяет содержимое операнда. Речь идет об операторах инкремента (++) и декремента ( -- ). Поскольку обычно эти операторы выполняют функции инкрементирования и декрементирования значений, соответственно, то перегруженные операторы "+" и " - " , как правило, инкрементируют свой операнд. Таким образом, при перегрузке этих операторов операнд обычно модифицируется. Например, рассмотрим метод operator++ () для класса ThreeD.

// Перегрузка унарного оператора "++".

public static ThreeD operator ++(ThreeD op)

{// Оператор "++" модифицирует аргумент.

op.x++;

op.y++;

op.z++;

return op;}

Обратите внимание: в результате выполнения этого операторного метода объект, на который ссылается операнд ор, модифицируется. Итак, операнд, подвергнутый операции "++", инкрементируется. Более того, модифицированный объект возвращается этим методом, благодаря чему оператор "++" можно использовать в более сложных выражениях.