Как перегрузить оператор c
Перейти к содержимому

Как перегрузить оператор c

Основы перегрузки операторов

XYZ School

В C#, подобно любому языку программирования, имеется готовый набор лексем, используемых для выполнения базовых операций над встроенными типами. Например, известно, что операция + может применяться к двум целым, чтобы дать их сумму:

Здесь нет ничего нового, но задумывались ли вы когда-нибудь о том, что одна и та же операция + может применяться к большинству встроенных типов данных C#? Например, рассмотрим такой код:

По сути, функциональность операции + уникальным образом базируются на представленных типах данных (строках или целых в данном случае). Когда операция + применяется к числовым типам, мы получаем арифметическую сумму операндов. Однако когда та же операция применяется к строковым типам, получается конкатенация строк.

Язык C# предоставляет возможность строить специальные классы и структуры, которые также уникально реагируют на один и тот же набор базовых лексем (вроде операции +). Имейте в виду, что абсолютно каждую встроенную операцию C# перегружать нельзя. В следующей таблице описаны возможности перегрузки основных операций:

Операция C# Возможность перегрузки
+, -, !, ++, —, true, false Этот набор унарных операций может быть перегружен
+, -, *, /, %, &, |, ^, > Эти бинарные операции могут быть перегружены
==, !=, <, &gt, <=, >= Эти операции сравнения могут быть перегружены. C# требует совместной перегрузки «подобных» операций (т.е. < и >, <= и >=, == и !=)
[] Операция [] не может быть перегружена. Oднако, аналогичную функциональность предлагают индексаторы
() Операция () не может быть перегружена. Однако ту же функциональность предоставляют специальные методы преобразования
+=, -=, *=, /=, %=, &=, |=, ^=, >= Сокращенные операции присваивания не могут перегружаться; однако вы получаете их автоматически, перегружая соответствующую бинарную операцию

Перегрузка операторов тесно связана с перегрузкой методов. Для перегрузки оператора служит ключевое слово operator, определяющее операторный метод, который, в свою очередь, определяет действие оператора относительно своего класса. Существуют две формы операторных методов (operator): одна — для унарных операторов, другая — для бинарных. Ниже приведена общая форма для каждой разновидности этих методов:

Здесь вместо op подставляется перегружаемый оператор, например + или /, а возвращаемый_тип обозначает конкретный тип значения, возвращаемого указанной операцией. Это значение может быть любого типа, но зачастую оно указывается такого же типа, как и у класса, для которого перегружается оператор. Такая корреляция упрощает применение перегружаемых операторов в выражениях. Для унарных операторов операнд обозначает передаваемый операнд, а для бинарных операторов то же самое обозначают операнд1 и операнд2. Обратите внимание на то, что операторные методы должны иметь оба спецификатора типа — public и static.

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

Давайте рассмотрим применение перегрузки бинарных операторов на простейшем примере:

Использование перегрузки бинарных операторов в C#

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

Унарные операторы перегружаются таким же образом, как и бинарные. Главное отличие заключается, конечно, в том, что у них имеется лишь один операнд. Давайте модернизируем предыдущий пример, дополнив перегрузки операций ++, —, -:

Использование перегрузки унарных операторов

Выполнение операций со встроенными в C# типами данных

Для любого заданного класса и оператора имеется также возможность перегрузить сам операторный метод. Это, в частности, требуется для того, чтобы разрешить операции с типом класса и другими типами данных, в том числе и встроенными. Давайте добавим следующую перегрузку в предыдущий пример:

Как подтверждает приведенный выше результат, когда оператор + применяется к двум объектам класса MyArr, то складываются их координаты. А когда он применяется к объекту типа MyArr и строковому значению, то возвращается строка с текущими координатами объекта.

C ++ — Перегрузка (оператор и функция)

C ++ позволяет указать более одного определения для функции имени или оператора в той же области, что называется функция перегрузки и перегрузки операторов соответственно.

Перегруженное объявление представляет собой объявление, объявленное с тем же именем, что и ранее объявленное объявление в той же области видимости, за исключением того, что обе декларации имеют разные аргументы и, очевидно, другое определение (реализация).

Когда вы вызываете перегруженную функцию или оператор , компилятор определяет наиболее подходящее определение для использования, сравнивая типы аргументов, которые вы использовали для вызова функции или оператора, с типами параметров, указанными в определениях. Процесс выбора наиболее подходящей перегруженной функции или оператора называется разрешением перегрузки .

Перегрузка функций в C ++

Вы можете иметь несколько определений для одного и того же имени функции в той же области. Определение функции должно отличаться друг от друга по типам и / или количеству аргументов в списке аргументов. Вы не можете перегружать объявления функций, которые отличаются только возвращаемым типом.

Ниже приведен пример, когда одна и та же функция print () используется для печати разных типов данных —

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Перегрузка операторов в C ++

Вы можете переопределить или перегрузить большинство встроенных операторов, доступных на C ++. Таким образом, программист может также использовать операторы с определенными пользователем типами.

Перегруженные операторы — это функции со специальными именами: ключевое слово «оператор», за которым следует символ для определяемого оператора. Как и любая другая функция, перегруженный оператор имеет тип возврата и список параметров.

объявляет оператор добавления, который можно использовать для добавления двух объектов Box и возвращает конечный объект Box. Большинство перегруженных операторов могут быть определены как обычные функции, не являющиеся членами, или как функции членов класса. В случае, если мы определяем функцию выше как функцию, не являющуюся членом класса, мы должны были бы передать два аргумента для каждого операнда следующим образом:

Ниже приведен пример, показывающий концепцию оператора при загрузке с использованием функции-члена. Здесь объект передается как аргумент, свойства которого будут доступны с помощью этого объекта, к объекту, который вызовет этот оператор, можно получить доступ с помощью этого оператора, как описано ниже —

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Определение и перегрузка операторов класса в C++

В C++ можно определять пользовательские операторы для собственных типов данных. Оператор определяется, как обычная функция-член класса, только после определения возвращаемого типа ставится ключевое слово operator .

Пример определения оператора сложения:

Оператор может быть унарным или бинарным. Унарный оператор не принимает никаких аргументов. Например, оператор отрицания — «!». Бинарный оператор принимает дополнительный параметр. Например, в случае со сложением, принимается второе слагаемое.

Чтобы прояснить картину, попробуем написать класс simple_fraction , который будет описывать простую дробь с целыми числителем и знаменателем. И определим операторы сложения, вычитания, умножения и деления для этого класса.

Для операции деления, мы также сделали проверку деления на ноль.

Пример использования класса simple_fraction :

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

Задание: усовершенствуйте класс simple_fraction . Перегрузите операторы сложения, вычитания, умножения и деления так, чтобы можно было производить операции над двумя простыми дробями и получать новую простую дробь. Реализуйте приведение двух дробей к общему знаменателю.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *