- •9 Перегрузка операторов
- •9.1 Основы перегрузки операторов
- •9.1.1 Перегрузка бинарных операторов
- •9.1.2 Перегрузка унарных операторов
- •9.2 Выполнение операций со встроенными в с# типами данных
- •9.3 Перегрузка операторов отношения
- •9.4 Перегрузка операторов true и false
- •9.5 Перегрузка логических операторов
- •9.5.1 Простой способ перегрузки логических операторов
- •9.5.2 Как сделать укороченные логические операторы доступными
- •9.5 Операторы преобразования
- •9.6 Рекомендации и ограничения по перегрузке операторов
- •9.6.1 Еще один пример перегрузки операторов
9.1.2 Перегрузка унарных операторов
Унарные операторы перегружаются таким же образом, как и бинарные. Главное отличие заключается, конечно, в том, что у них имеется лишь один операнд. В качестве примера ниже приведен метод, перегружающий оператор унарного минуса для класса ThreeD.
Листинг 9.2
// Перегрузить оператор унарного минуса.
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 не меняется.
В С# перегрузка операторов ++ и -- осуществляется довольно просто. Для этого достаточно возвратить инкрементированное или декрементированное значение, но не изменять вызывающий объект. А все остальное возьмет на себя компилятор С#, различая префиксные и постфиксные формы этих операторов. В качестве примера ниже приведен операторный метод operator++() для класса ThreeD.
Листинг 9.3
// Перегрузить унарный оператор ++.
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;
}
Ниже приведен расширенный вариант предыдущего примера программы, в кото ром демонстрируется перегрузка унарных операторов - и ++.
Листинг 9.4
// Пример перегрузки бинарных и унарных операторов.
using System;
// Класс для хранения трехмерных координат.
class ThreeD
{
int x, y, z; // трехмерные координаты
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;
}
// Перегрузить бинарный оператор -.
public static ThreeD operator -(ThreeD op1, ThreeD op2)
{
ThreeD result = new ThreeD();
/* Обратить внимание на порядок следования операндов:
op1 – левый операнд, а op2 – правый операнд. */
result.x = op1.x - op2.x;
result.y = op1.y - op2.y;
result.z = op1.z - op2.z;
return result;
}
// Перегрузить унарный оператор -.
public static ThreeD operator -(ThreeD op)
{
ThreeD result = new ThreeD();
result.x = -op.x;
result.y = -op.y;
result.z = -op.z;
return result;
}
// Перегрузить унарный оператор ++.
public static ThreeD operator ++(ThreeD op)
{
ThreeD result = new ThreeD();
// Возвратить результат инкрементирования.
result.x = op.x + 1;
result.y = op.y + 1;
result.z = op.z + 1;
return result;
}
// Вывести координаты X, Y, Z.
public void Show()
{
Console.WriteLine(x + ", " + y + ", " + z);
}
}
class ThreeDDemo
{
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; // сложить координаты точек a и b
Console.Write("Результат сложения a + b: ");
c.Show();
Console.WriteLine();
c = a + b + c; // сложить координаты точек a, b и c
Console.Write("Результат сложения a + b + c: ");
c.Show();
Console.WriteLine();
c = c - a; // вычесть координаты точки a
Console.Write("Результат вычитания c - a: ");
c.Show();
Console.WriteLine();
c = c - b; // вычесть координаты точки b
Console.Write("Результат вычитания c - b: ");
c.Show();
Console.WriteLine();
c = -a; // присвоить точке с отрицательные координаты точки а
Console.Write("Результат присваивания -a: ");
c.Show();
Console.WriteLine();
c = a++; // присвоить точке с координаты точки а,
// а затем инкрементировать их
Console.WriteLine("Если c = a++");
Console.Write("то координаты точки c равны ");
c.Show();
Console.Write("а координаты точки a равны ");
a.Show();
// Установить исходные координаты (1,2,3) точки а
a = new ThreeD(1, 2, 3);
Console.Write("\nУстановка исходных координат точки a: ");
a.Show();
c = ++a; // инкрементировать координаты точки а,
// а затем присвоить их точке c
Console.WriteLine("\nЕсли c = ++a");
Console.Write("то координаты точки c равны ");
c.Show();
Console.Write("а координаты точки a равны ");
a.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
