Перегрузка операторов сравнения ==, !=, <, >, <=, >=. Перегрузка логических побитовых операторов &, |, ^
Содержание
- 1. Перегрузка бинарных операторов сравнения ==, !=. Пример
- 2. Перегрузка бинарных операторов сравнения <, >, <=, >=. Пример
- 3. Перегрузка битовых бинарных операторов & (логическое побитовое «И»), | (логическое побитовое «ИЛИ»), ^ (сложение по модулю 2)
- 4. Перегрузка операторов сдвига <<, >>. Пример
- Связанные темы
Поиск на других ресурсах:
1. Перегрузка бинарных операторов сравнения ==, !=. Пример
Операторы сравнения ==, != можно перегружать в классе. Особенность этих операторов состоит в том, что нужно реализовывать оба оператора одновременно.
Демонстрируется использование бинарных операторов сравнения для класса ArrayRange, реализующего массив целых чисел, находящихся в заданном диапазоне. В классе перегружаются операторы == и !=. Эти операторы производят поэлементное сравнение двух объектов типа ArrayRange.
Обязательна перегрузка этих операторов в паре. Если перегружается оператор ==, то нужно перегружать оператор !=.
using System; namespace ConsoleApp6 { class ArrayRange { // Внутреннее поле - массив private int[] A; private int min; // минимальное значение private int max; // максимальное значение // Конструктор public ArrayRange(int[] _A, int _min, int _max) { // Установить границы if (_min <= _max) { min = _min; max = _max; } if (_min >= _max) { min = _max; max = _min; } // Сделать копию из исходного массива _A A = new int[_A.Length]; for (int i = 0; i < A.Length; i++) { if (_A[i] < min) A[i] = min; else if (_A[i] > max) A[i] = max; else A[i] = _A[i]; } } // Метод вывода внутреннего массива public void Print(string msg) { Console.WriteLine(msg); for (int i = 0; i < A.Length; i++) Console.Write(A[i] + " "); Console.WriteLine(); Console.WriteLine("-----------------------------"); } // Метод, возвращающий ссылку на массив A public int[] Get() { return A; } // Метод, который перегружает оператор == public static bool operator==(ArrayRange A1, ArrayRange A2) { // 1. Сравнение расстояний if (A1.A.Length != A2.A.Length) return false; // 2. Поэлементное сравнение for (int i = 0; i < A1.A.Length; i++) if (A1.A[i] != A2.A[i]) return false; return true; } // Метод, который перегружает оператор != public static bool operator!=(ArrayRange A1, ArrayRange A2) { return !(A1 == A2); } } internal class Program { static void Main(string[] args) { // 1. Создать массивы типа int[] int[] AI1 = { 2, 8, 1, -3, 4 }; int[] AI2 = { 2, 8, 1, -3, 4 }; // 2. Создать массивы типа ArrayRange ArrayRange A1 = new ArrayRange(AI1, 1, 5); ArrayRange A2 = new ArrayRange(AI2, 1, 5); // 3. Вывести массивы A1.Print("A1"); A2.Print("A2"); // 4. Вызвать перегруженный оператор сравнения массивов == if (A1 == A2) Console.WriteLine("A1 == A2"); else Console.WriteLine("A1 != A2"); // 5. Вызвать другой перегруженный оператор != if (A1 != A2) Console.WriteLine("A1 != A2"); else Console.WriteLine("A1 == A2"); Console.ReadKey(); } } }
Результат
A1 2 5 1 1 4 ----------------------------- A2 2 5 1 1 4 ----------------------------- A1 == A2 A1 == A2
⇑
2. Перегрузка бинарных операторов сравнения <, >, <=, >=. Пример
Перегрузка бинарных операторов сравнения >, <, >=, <= должна быть реализована попарно. Это означает, что обязательно нужно реализовывать следующие пары операторов:
- > и <;
- >= и <=.
На примере класса Line демонстрируется перегрузка бинарных операторов сравнения >, <, >=, <=. Методы класса
operator<() operator>() operator>=() operator<=()
возвращают результат сравнения длин отрезков, являющихся входными параметрами.
using System; namespace ConsoleApp6 { // Класс, описывающий линию, состоящую из двух точек class Line { // Внутренние переменные - координаты отрезка private double x1, y1, x2, y2; // Конструктор public Line(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } // Свойства доступа public double X1 { get { return x1; } } public double Y1 { get { return y1; } } public double X2 { get { return x2; } } public double Y2 { get { return y2; } } // Метод, выводящий координаты линии public void Print(string msg) { Console.Write(msg + "=> ( " + x1 + "; " + y1 + ") - ( " + x2 + "; " + y2 + "), "); Console.WriteLine(" length = {0:f2}", Length()); } // Метод, возвращающий длину отрезка public double Length() { return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } // Перегруженные методы <, >, <=, >=. // В методах сравниваются длины отрезков ln1 и ln2 public static bool operator>(Line ln1, Line ln2) { return ln1.Length() > ln2.Length(); } public static bool operator<(Line ln1, Line ln2) { return !(ln1 > ln2); } public static bool operator>=(Line ln1, Line ln2) { return ln1.Length() >= ln2.Length(); } public static bool operator <=(Line ln1, Line ln2) { return ln1.Length() <= ln2.Length(); } } internal class Program { static void Main(string[] args) { // 1. Объявить 2 отрезка Line ln1 = new Line(1, 1, 2, 4); Line ln2 = new Line(3, 5, -1, -7); // 2. Вывести информацию об отрезках ln1, ln2 ln1.Print("ln1"); ln2.Print("ln2"); // 3. Сравнить ln1 < ln2 if (ln1 < ln2) Console.WriteLine("ln1 < ln2"); else Console.WriteLine("ln1 >= ln2"); // 4. Сравнить ln1 > ln2 if (ln1 > ln2) Console.WriteLine("ln1 > ln2"); else Console.WriteLine("ln1 <= ln2"); // 5. Сравнить ln1 <= ln2 if (ln1 <= ln2) Console.WriteLine("ln1 <= ln2"); else Console.WriteLine("ln1 > ln2"); // 6. Сравнить ln1 >= ln2 if (ln1 >= ln2) Console.WriteLine("ln1 >= ln2"); else Console.WriteLine("ln1 < ln2"); Console.ReadKey(); } } }
Результат
ln1=> ( 1; 1) - ( 2; 4), length = 3.16 ln2=> ( 3; 5) - ( -1; -7), length = 12.65 ln1 < ln2 ln1 <= ln2 ln1 <= ln2 ln1 < ln2
⇑
3. Перегрузка битовых бинарных операторов & (логическое побитовое «И»), | (логическое побитовое «ИЛИ»), ^ (сложение по модулю 2)
В примере показано поэлементное оперирование массивами, состоящими из 0 и 1. Задан класс ArrayBits, в котором объявляется массив типа byte[]. Элементы массива состоят из значений 0 и 1. В классе перегружаются логические побитовые операторы &, |, ^.
Методы, которые перегружают операторы реализуют соответствующие операции над каждым элементом массива. Операторный метод operator&() выполняет побитовое логическое «И» над элементами двух массивов. Операторный метод operator|() выполняет побитовое логическое «ИЛИ» над элементами массивов. Соответственно метод operator^() выполняет побитовое логическое сложение над каждым из элементов массива.
Демонстрационный программный код консольного приложения следующий.
using System; namespace ConsoleApp6 { // Класс, описывающий массив битов 0, 1 class ArrayBits { private byte[] AB; // Конструктор public ArrayBits(byte[] _AB) { // Создать новый массив, в котором ненулевые значения равны 1, // а нулевые значения равны 0 AB = new byte[_AB.Length]; for (int i = 0; i < _AB.Length; i++) if (_AB[i] != 0) AB[i] = 1; else AB[i] = 0; } // Метод, который выводит внутренний массив AB public void Print(string msg) { Console.Write(msg + " => "); for (int i = 0; i < AB.Length; i++) Console.Write(AB[i] + " "); Console.WriteLine(); } // Перегрузка операторов &, |, ^ // Побитовое "И" public static ArrayBits operator&(ArrayBits AB1, ArrayBits AB2) { ArrayBits res; // Выбрать массив с наименьшей длиной // и на его основе создать результирующий массив if (AB1.AB.Length<AB2.AB.Length) { res = new ArrayBits(AB1.AB); } else { res = new ArrayBits(AB2.AB); } // Реализовать поэлементное побитовое "И", // сформировать массив res for (int i = 0; i < res.AB.Length; i++) if ((AB1.AB[i] == 1) && (AB2.AB[i] == 1)) res.AB[i] = 1; else res.AB[i] = 0; // Вернуть результирующий массив return res; } // Побитовое "ИЛИ" public static ArrayBits operator|(ArrayBits AB1, ArrayBits AB2) { ArrayBits res; // Выбрать массив с наименьшей длиной // и на его основе создать результирующий массив if (AB1.AB.Length < AB2.AB.Length) { res = new ArrayBits(AB1.AB); } else { res = new ArrayBits(AB2.AB); } // Реализовать поэлементное побитовое "ИЛИ", // сформировать массив res for (int i = 0; i < res.AB.Length; i++) if ((AB1.AB[i] == 0) && (AB2.AB[i] == 0)) res.AB[i] = 0; else res.AB[i] = 1; // Вернуть результирующий массив return res; } // Побитовое сложение по модулю 2 public static ArrayBits operator^(ArrayBits AB1, ArrayBits AB2) { ArrayBits res; // Выбрать массив с наименьшей длиной // и на его основе создать результирующий массив if (AB1.AB.Length < AB2.AB.Length) { res = new ArrayBits(AB1.AB); } else { res = new ArrayBits(AB2.AB); } // Реализовать поэлементное побитовое сложение по модулю 2, // сформировать массив res for (int i = 0; i < res.AB.Length; i++) if (AB1.AB[i] == AB2.AB[i]) res.AB[i] = 0; else res.AB[i] = 1; // Вернуть результирующий массив return res; } } internal class Program { static void Main(string[] args) { // 1. Создать 2 тестируемых массива типа byte[] byte[] A1 = { 2, 3, 0, 0, 4, 7, 0, 55 }; byte[] A2 = { 1, 0, 6, 0, 2, 0, 8, 9, 4, 0, 0 }; // 2. Создать 2 объекта на основе массивов A1 и A2 ArrayBits AB1 = new ArrayBits(A1); ArrayBits AB2 = new ArrayBits(A2); // 3. Вывести массивы в экземплярах для контроля AB1.Print("AB1 "); AB2.Print("AB2 "); // 4. Реализовать побитовое & - И ArrayBits AB3; AB3 = AB1 & AB2; // => ArrayBits.operator&(AB1, AB2); AB3.Print("AB1 & AB2"); // 5. Вывести результат побитового | - ИЛИ (AB1 | AB2).Print("AB1 | AB2"); // => ArrayBits.operator|(AB1, AB2); // 6. Реализовать побитовое ^ - сложение по модулю 2 ArrayBits AB4 = AB1 ^ AB2; // => ArrayBits.operator^(AB1, AB2); AB4.Print("AB1 ^ AB2"); Console.ReadKey(); } } }
Результат
AB1 => 1 1 0 0 1 1 0 1 AB2 => 1 0 1 0 1 0 1 1 1 0 0 AB1 & AB2 => 1 0 0 0 1 0 0 1 AB1 | AB2 => 1 1 1 0 1 1 1 1 AB1 ^ AB2 => 0 1 1 0 0 1 1 0
⇑
4. Перегрузка операторов сдвига <<, >>. Пример
В классе операторы сдвига перегружаются в паре. Это означает, что если перегружается оператор << (сдвиг влево), то также нужно перегружать оператор >> (сдвиг вправо).
using System; namespace ConsoleApp6 { // Массив целых чисел class ArrayInt { private int[] AI; // Конструктор public ArrayInt(int[] _AD) { // Копирование AD = _AD AI = new int[_AD.Length]; for (int i = 0; i < AI.Length; i++) AI[i] = _AD[i]; } // Метод, который выводит массив AD public void Print(string msg) { Console.Write(msg + " => "); for (int i = 0; i < AI.Length; i++) Console.Write(AI[i] + " "); Console.WriteLine(); } // Перегрузка оператора сдвига влево << // Элементи массива сдвигаются циклически влево, // первый элемент массива становится на место последнего. // Обратить внимание: метод возвращает экземпляр типа ArrayInt и целое число int public static ArrayInt operator<<(ArrayInt AI, int n) { // 1. Создать экземпляр массива AI ArrayInt res = new ArrayInt(AI.AI); for (int k = 0; k < n; k++) { // Циклический сдвиг на одну позицию влево int t = res.AI[0]; for (int i = 0; i < res.AI.Length - 1; i++) res.AI[i] = res.AI[i + 1]; res.AI[AI.AI.Length - 1] = t; } // 2. Результирующий экземпляр return res; } // Операторный метод, перегружающий оператор >> сдвига вправо public static ArrayInt operator >>(ArrayInt AI, int n) { // 1. Создать экземпляр массива AI ArrayInt res = new ArrayInt(AI.AI); for (int k = 0; k < n; k++) { // Циклический сдвиг на одну позицию влево int t = res.AI[AI.AI.Length - 1]; for (int i = res.AI.Length - 1; i >= 1; i--) res.AI[i] = res.AI[i - 1]; res.AI[0] = t; } // 2. Результирующий экземпляр return res; } } internal class Program { static void Main(string[] args) { // 1. Объявить массив типа int[] int[] A = { 2, 8, 9, 15, 27 }; // 2. Создать экземпляр типа ArrayInt ArrayInt AI = new ArrayInt(A); AI.Print("AI "); // Вывести массив // 3. Вызвать оператор сдвига влево на 2 позиции ArrayInt res = AI << 2; res.Print("AI << 2"); // 4. Вызвать оператор сдвига вправо на 4 позиции res = AI >> 4; res.Print("AI >> 4"); Console.ReadKey(); } } }
Результат
AI => 2 8 9 15 27 AI << 2 => 9 15 27 2 8 AI >> 4 => 8 9 15 27 2
⇑
Связанные темы
- Перегрузка операторов. Общие сведения. Перегрузка унарных операторов. –, !, ++, —
- Перегрузка операторов сравнения ==, !=, <, >, <=, >=. Перегрузка логических побитовых операторов
⇑