Оператор не имеет результата требуется оператор с побочным действием
Текущая версия страницы пока не проверялась опытными участниками и может значительно отличаться от версии, проверенной 14 августа 2019;
проверки требуют 12 правок.
Язык программирования C++, поддерживает все операторы своего прародителя Си и дополнен новыми операторами и возможностями.
- например операторами приведения типа:
- const_cast
- static_cast
- dynamic_cast
- reinterpret_cast
- возможность перегрузки операторов;
После вычисления первого операнда для неперегруженных операторов «&&», «||» и «,» (оператор «запятая», англ. comma) компилятор вставляет точку следования (англ. sequence point), гарантирующую, что все побочные эффекты (например, оператор «постфиксный ++») будут выполнены до начала вычисления второго операнда.
Языки с Си-подобным синтаксисом (например, Java, C#, PHP и другие) часто заимствуют операторы Cи/C++ с сохранением не только поведения, но также приоритета и ассоциативности.
Таблицы[править | править код]
struct T { // или class
operator float () const;
};
T::operator float () const { /* реализация */ };
- «Определение вне класса»: определение оператора в виде функции; пример:
#include <iostream>
struct T { // или class
/* … */
};
std::ostream & operator << ( std::ostream & a, T const & b ) { /* реализация */ }
- «Н/Д»: недоступно.
Арифметические операторы[править | править код]
Операция (выражение) | Оператор | Синтаксис выражения | Перегружаемый | Реализован в Си | Пример | ||
---|---|---|---|---|---|---|---|
Член типа T | Определение вне класса | ||||||
Присваивание | = | a = b | Да | Да | R& T::operator =(S b); | н/д | |
Сложение | + | a + b | Да | Да | R T::operator +(S b); | R operator +(T a, S b); | |
Вычитание | — | a — b | Да | Да | R T::operator -(S b); | R operator -(T a, S b); | |
Унарный плюс | + | +a | Да | Да | R T::operator +(); | R operator +(T a); | |
Унарный минус | — | —a | Да | Да | R T::operator -(); | R operator -(T a); | |
Умножение | * | a * b | Да | Да | R T::operator *(S b); | R operator *(T a, S b); | |
Деление | / | a / b | Да | Да | R T::operator /(S b); | R operator /(T a, S b); | |
Операция модуль (остаток от деления целых чисел)[note 1] | % | a % b | Да | Да | R T::operator %(S b); | R operator %(T a, S b); | |
Инкремент | префиксный | ++ | ++a | Да | Да | R& T::operator ++(); | R& operator ++(T a); |
суффиксный (постфиксный) | ++ | a++ | Да | Да | R T::operator ++(int); | R operator ++(T a, int); | |
[note 2] | |||||||
Декремент | префиксный | — | —a | Да | Да | R& T::operator —(); | R& operator —(T a); |
суффиксный (постфиксный) | — | a— | Да | Да | R T::operator —(int); | R operator —(T a, int); | |
[note 2] |
Операторы сравнения[править | править код]
Операция (выражение) | Оператор | Синтаксис выражения | Перегружаемый | Реализован в Си | Пример | |
---|---|---|---|---|---|---|
Член типа T | Определение вне класса | |||||
Равенство | == | a == b | Да | Да | R T::operator ==(S b); | R operator ==(T a, S b); |
Неравенство | != | a != b | Да | Да | R T::operator !=(S b); | R operator !=(T a, S b); |
Больше | > | a > b | Да | Да | R T::operator >(S b); | R operator >(T a, S b); |
Меньше | < | a < b | Да | Да | R T::operator <(S b); | R operator <(T a, S b); |
Больше или равно | >= | a >= b | Да | Да | R T::operator >=(S b); | R operator >=(T a, S b); |
Меньше или равно | <= | a <= b | Да | Да | R T::operator <=(S b); | R operator <=(T a, S b); |
Логические операторы[править | править код]
Операция (выражение) | Оператор | Синтаксис выражения | Перегружаемый | Реализован в Си | Пример | |
---|---|---|---|---|---|---|
Член типа T | Определение вне класса | |||||
Логическое отрицание, НЕ | ! | !a | Да | Да | R T::operator !(); | R operator !(T a); |
Логическое умножение, И | && | a && b | Да | Да | R T::operator &&(S b); | R operator &&(T a, S b); |
Логическое сложение, ИЛИ | || | a || b | Да | Да | R T::operator ||(S b); | R operator ||(T a, S b); |
Побитовые операторы[править | править код]
Операция (выражение) | Оператор | Синтаксис выражения | Перегружаемый | Реализован в Си | Пример | |
---|---|---|---|---|---|---|
Член типа T | Определение вне класса | |||||
Побитовая инверсия | ~ | ~a | Да | Да | R T::operator ~(); | R operator ~(T a); |
Побитовое И | & | a & b | Да | Да | R T::operator &(S b); | R operator &(T a, S b); |
Побитовое ИЛИ (or) | | | a | b | Да | Да | R T::operator |(S b); | R operator |(T a, S b); |
Побитовое исключающее ИЛИ (xor) | ^ | a ^ b | Да | Да | R T::operator ^(S b); | R operator ^(T a, S b); |
Побитовый сдвиг влево[note 3] | << | a << b | Да | Да | R T::operator <<(S b); | R operator <<(T a, S b); |
Побитовый сдвиг вправо[note 3][note 4] | >> | a >> b | Да | Да | R T::operator >>(S b); | R operator >>(T a, S b); |
Составное присваивание[править | править код]
Операция (выражение) | Оператор | Синтаксис выражения | Значение | Перегружаемый | Реализован в Си | Пример | |
---|---|---|---|---|---|---|---|
Член типа T | Определение вне класса | ||||||
Сложение, совмещённое с присваиванием | += | a += b | a = a + b | Да | Да | R T::operator +=(S b); | R operator +=(T a, S b); |
Вычитание, совмещённое с присваиванием | -= | a -= b | a = a — b | Да | Да | R T::operator -=(S b); | R operator -=(T a, S b); |
Умножение, совмещённое с присваиванием | *= | a *= b | a = a * b | Да | Да | R T::operator *=(S b); | R operator *=(T a, S b); |
Деление, совмещённое с присваиванием | /= | a /= b | a = a / b | Да | Да | R T::operator /=(S b); | R operator /=(T a, S b); |
Вычисление остатка от деления, совмещённое с присваиванием[note 1] | %= | a %= b | a = a % b | Да | Да | R T::operator %=(S b); | R operator %=(T a, S b); |
Побитовое «И» (AND), совмещённое с присваиванием | &= | a &= b | a = a & b | Да | Да | R T::operator &=(S b); | R operator &=(T a, S b); |
Побитовое «ИЛИ» (or), совмещённое с присваиванием | |= | a |= b | a = a | b | Да | Да | R T::operator |=(S b); | R operator |=(T a, S b); |
Побитовое «исключающее ИЛИ» (xor), совмещённое с присваиванием | ^= | a ^= b | a = a ^ b | Да | Да | R T::operator ^=(S b); | R operator ^=(T a, S b); |
Побитовый сдвиг влево, совмещённый с присваиванием | <<= | a <<= b | a = a << b | Да | Да | R T::operator <<=(S b); | R operator <<=(T a, S b); |
Побитовый сдвиг вправо, совмещённый с присваиванием[note 4] | >>= | a >>= b | a = a >> b | Да | Да | R T::operator >>=(S b); | R operator >>=(T a, S b); |
Операторы работы с указателями и членами класса[править | править код]
Оператор | Синтаксис | Перегружаемый | Реализован в Си | Пример | ||
---|---|---|---|---|---|---|
Член типа T | Определение вне класса | |||||
Обращение к элементу массива | a[b] | Да | Да | R T::operator [](S b); | н/д | |
Непрямое обращение («объект, на который указывает a») | *a | Да | Да | R T::operator *(); | R operator *(T a); | |
Ссылка («адрес a») | &a | Да | Да | R T::operator &(); | R operator &(T a); | |
Обращение к члену структуры («член b объекта, на который указывает a») | a->b | Да | Да | R* T::operator ->();[note 5] | н/д | |
Обращение к члену структуры («член b объекта a») | a.b | Нет | Да | н/д | ||
Член, на который указывает b в объекте, на который указывает a[note 6] | a->*b | Да | Нет | R T::operator ->*(S b); | R operator ->*(T a, S b); | |
Член, на который указывает b в объекте a | a.*b | Нет | Нет | н/д |
Другие операторы[править | править код]
Оператор | Синтаксис | Перегружаемый | Реализован в Си | Пример | ||
---|---|---|---|---|---|---|
Член типа T | Определение вне класса | |||||
Функтор | a(a1, a2) | Да | Да | R T::operator ()(S a1, U a2, …); | н/д | |
Оператор «запятая» | a, b | Да | Да | R T::operator ,(S b); | R operator ,(T a, S b); | |
Тернарная условная операция | a ? b : c | Нет | Да | н/д | ||
Оператор расширения области видимости | a::b | Нет | Нет | н/д | ||
Sizeof (размер) | sizeof(a)[note 7] sizeof(type) | Нет | Да | н/д | ||
Align-of (выравнивание) | alignof(type) или _Alignof(type)[note 8] | Нет | Да | н/д | ||
Интроспекция | typeid(a) typeid(type) | Нет | Нет | н/д | ||
Приведение типа | (type) a | Да | Да | T::operator R(); | н/д | |
[note 9] | ||||||
Выделение памяти | new type | Да | Нет | void* T::operator new(size_t x); | void* operator new(size_t x); | |
Выделение памяти для массива | new type[n] | Да | Нет | void* T::operator new[](size_t x); | void* operator new[](size_t x); | |
Освобождение памяти | delete a | Да | Нет | void T::operator delete(void* x); | void operator delete(void* x); | |
Освобождение памяти, занятой массивом | delete[] a | Да | Нет | void T::operator delete[](void* x); | void operator delete[](void* x); |
Примечания:
- ↑ 1 2 Оператор «%» работает только с целыми числами. Для чисел с плавающей точкой используйте функцию fmod() из файла «math.h».
- ↑ 1 2 Чтобы отличить префиксный и суффиксный (постфиксный) операторы друг от друга, у постфиксных операторов добавлен неиспользуемый формальный параметр типа int. Часто этому параметру даже не дают имя.
- ↑ 1 2 В библиотеке «iostream» операторы «<<» и «>>» используются для работы с потоковым выводом и вводом.
- ↑ 1 2 По стандарту C99, сдвиг вправо отрицательного числа — implementation defined behavior (см. неуточняемое поведение). Многие компиляторы, в том числе gcc (см. документацию (англ.)), реализуют арифметический сдвиг, но стандарт не запрещает реализовывать логический сдвиг.
- ↑ Тип возвращаемого значения оператора «operator->()» должен быть типом, к которому применим оператор «->», например, указателем. Если «x» имеет тип «C», и класс «C» перегружает оператор «operator->()», выражение «x->y» раскрывается как «x.operator->()->y».
- ↑ См. пример в статье (англ.) «Реализация оператора ->* для умных указателей» Скотта Майерса из журнала «Dr. Dobb’s journal», выпуск за октябрь 1999 года.
- ↑ Оператор sizeof, обычно, записывают со скобками. Если операнд — имя переменной, указание скобок необязательно. Если операнд — имя типа, скобки обязательны.
- ↑ Стандарт языка C++ определяет оператор alignof. Аналогичный оператор в стандарте языка Си называется _Alignof.
- ↑ Для оператора приведения типа тип возвращаемого значения явно не указывается, так как совпадает с именем оператора.
Приоритеты операторов[править | править код]
В данной таблице указаны приоритеты операторов и их ассоциативность. Операторы, указанные в таблице выше (раньше), имеют более высокий приоритет (приоритет вычисления). При рассмотрении выражения, операторы, имеющие более высокий приоритет, будут вычислены раньше операторов с низким приоритетом. Если несколько операторов указаны в одной ячейке, то они имеют одинаковый приоритет и вычисляются в последовательности, задаваемой ассоциативностью. Приоритеты операторов не изменяются при их перегрузке.
Этой таблицы приоритетов в большинстве случаев бывает достаточно, за исключением следующих случаев. Тернарный оператор «?:» может содержать в среднем выражении оператор «запятая» или присваивание, но код «a ? b, c : d» компилятор воспринимает как «a ? (b, c) : d», а не как бессмысленное выражение «(a ? b), (c : d)». Таким образом выражение между ? и : воспринимается, как если бы оно было в скобках.
Приоритет | Оператор | Описание | Ассоциативность |
---|---|---|---|
1 Наивысший | :: | Раскрытие области видимости | Нет |
2 | ++ | Суффиксный инкремент | Слева направо |
— | Суффиксный декремент | ||
() | Вызов функции | ||
[] | Взятие элемента массива | ||
. | Выбор элемента по ссылке | ||
-> | Выбор элемента по указателю | ||
typeid() | RTTI (только C++; см typeid) | ||
const_cast | Приведение типа (C++) (см const cast) | ||
dynamic_cast | Приведение типа (C++) (см dynamic cast) | ||
reinterpret_cast | Каламбур типизации (C++) (см reinterpret_cast) | ||
static_cast | Приведение типа (C++) (см static cast) | ||
3 | ++ | Префиксный инкремент | Справа налево |
— | Префиксный декремент | ||
+ | Унарный плюс | ||
— | Унарный минус | ||
! | Логическое НЕ | ||
~ | Побитовое НЕ | ||
(type) | Приведение типа | ||
* | Разыменование указателя | ||
& | Взятие адреса объекта | ||
sizeof | Sizeof (размер) | ||
new, new[] | Выделение динамической памяти (C++) | ||
delete, delete[] | Освобождение динамической памяти (C++) | ||
4 | .* | Указатель на член (C++) | Слева направо |
->* | Указатель на член (C++) | ||
5 | * | Умножение | |
/ | Деление | ||
% | Получение остатка от деления | ||
6 | + | Сложение | |
— | Вычитание | ||
7 | << | Побитовый сдвиг влево | |
>> | Побитовый сдвиг вправо | ||
8 | < | Меньше | |
<= | Меньше или равно | ||
> | Больше | ||
>= | Больше или равно | ||
9 | == | Равенство | |
!= | Неравенство | ||
10 | & | Побитовое И (and) | |
11 | ^ | Побитовое исключающее ИЛИ (xor) | |
12 | | | Побитовое ИЛИ (or) | |
13 | && | Логическое И | |
14 | || | Логическое ИЛИ | |
15 | ?: | Тернарная условная операция | Справа налево |
= | Присваивание | ||
+= | Сложение, совмещённое с присваиванием | ||
-= | Вычитание, совмещённое с присваиванием | ||
*= | Умножение, совмещённое с присваиванием | ||
/= | Деление, совмещённое с присваиванием | ||
%= | Вычисление остатка от деления, совмещённое с присваиванием | ||
<<= | Побитовый сдвиг влево, совмещённый с присваиванием | ||
>>= | Побитовый сдвиг вправо, совмещённый с присваиванием | ||
&= | Побитовое «И», совмещённое с присваиванием | ||
|= | Побитовое «ИЛИ», совмещённое с присваиванием | ||
^= | Побитовое «исключающее ИЛИ» (xor), совмещённое с присваиванием | ||
throw | Оператор создания исключения (C++) | ||
16 | , | Оператор «запятая» | Слева направо |
Описание[править | править код]
Компилятор использует таблицу приоритетов для определения порядка вычисления операторов.
- Например, ++x*3 был бы двусмысленным без каких-либо правил приоритетов. По таблице можно сказать, что x сначала связывается с оператором ++, и только затем с оператором *, поэтому независимо от действия оператора ++, это действие только над x (а не над x*3). Таким образом, выражение эквивалентно (++x, x*3).
- Аналогично с кодом 3*x++, где таблица утверждает, что инкремент применяется только к x а не к 3*x. Функционально это выражение эквивалентно (tmp=x, x++, tmp=3*tmp, tmp), если выразить временную переменную как tmp.
Связывание операторов в стандартах Си и C++ определено через грамматику языка, а не через таблицу. Это может создать конфликт. Например, в языке Си синтаксис условного оператора таков:
logical-OR-expression ? expression : conditional-expression
А в языке C++:
logical-OR-expression ? expression : assignment-expression
Из-за этого выражение:
будет воспринято по-разному в этих двух языках. В Си выражение синтаксически некорректно, так как результат условного оператора не может служить lvalue (то есть, левой частью оператора присваивания).
В C++, выражение будет разобрано как корректное:[1]
e = (a < d ? a++ : (a = d))
Приоритеты побитовых логических операторов несколько неинтуитивны[2]. Концептуально & и | являются такими же арифметическими операторами как * и + соответственно.
Выражение a & b == 7 синтаксически воспринимается как a & (b == 7), но выражение a + b == 7 эквивалентно (a + b) == 7. Из-за этого часто требуется пользоваться скобками для явного задания порядка вычислений.
Синонимы операторов в C++[править | править код]
В стандарте C++ определены[3]диграфы для некоторых операторов:
Диграф | Эквивалентная строка |
---|---|
and | && |
bitand | & |
and_eq | &= |
or | || |
bitor | | |
or_eq | |= |
xor | ^ |
xor_eq | ^= |
not | ! |
not_eq | != |
compl | ~ |
Диграфы могут использоваться точно так же как и операторы, являются синонимами операторов. Например, диграф «bitand» может использоваться для замены операторов «побитовое И» и «получение адреса» или в определении ссылочных типов. Так, код «int bitand ref = n;» эквивалентен коду «int & ref = n;».
Стандарт ANSI/ISO C определяет перечисленные диграфы в виде констант #define (см. препроцессор). Константы определены в заголовочном файле «iso646.h». Для совместимости с Си стандарт C++ определяет фиктивный заголовочный файл «ciso646».
Примечания[править | править код]
Ссылки[править | править код]
- Статья (англ.) «Операторы C++» на сайте cppreference.com.
- Статья (англ.) «Префиксные и постфиксные операторы в языках Си и C++» на сайте msdn.microsoft.com.
- ISO/IEC 14882
В языке программирования С# процесс, который позволяет определять назначение оператора по отношению к создаваемому классу, называется перегрузка операторов. Он расширяет область применения оператора в классе. Поведение оператора можно менять и контролировать.
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
Перегрузка операторов в языке программирования C#
Перегрузка операций в С# похожа на переопределение методов. В языке С# в зависимости от типа оператора объявляется оно двумя способами.
// перегрузка унарного оператора
public static тип operator primer(тип_параметра операнд)
{
// запросы
}
// перегрузка бинарного оператора
public static тип operator primer (тип_параметра1 операнд1, тип_параметра1 операнд2)
{
// запросы
}
Метод объявляется модификаторами public и static. Оператор, который перегружается должен быть одного типа с операндами.
Во время перегрузки оператора его функция и свойство не теряется, он только выполняет еще одну операцию. К примеру, оператор + используется для работы со списком при этом его назначение к сложению целых чисел не меняется. Когда оператор + используется со строковыми данными, выполняется перегрузка оператора со стороны класса String.
В С# существует операторы «+», «-», «!», «==», «!=» и другие, которые предназначены для работы с типами данных.
Так как в языке программирования С# используются готовые алгоритмы базовых операций, в некоторых моментах важна перегрузка операторов. Например, когда используем оператор + для целых чисел он возвращает сумму чисел, а если использовать его для строковых типов данных тогда выполняется объединение двух строк.
string a = «Сергей «;
string b = «Сергеев»;
string c = a + b; //результат «Сергей Сергеев»
Перегрузка операторовпозволяет добавлять удобный синтаксис для работы с классом в среду программирования. Это возможность одна из сильных сторон объектно-ориентированного языка программирования С#.
Когда в классе присутствует перегруженный оператор, компилятор сначала выполняет поведение определенное пользователем, если не определено, то осуществляется стандартная реализация.
Перегрузка операторов С# делает код красивее. Мы задаем, редактируем, или сами можем придумывать поведение определенного нами класса. Используя унарные, бинарные операторы, операторы сравнения и логические операторы мы задаем определенное действие компилятору.
Например, есть класс «точки» с координатами х и у. Два целых числа, объединенные одним классом. Мы можем сложить эти две точки. Даже если компилятор умный, система не в состоянии понять какое сложение точек выполнить. Поэтому нужно перегружать оператор, чтобы объяснить компилятору, как системе себя вести и какое действие выполнить. Возможно системе нужно сложить между собой все х или же сложить все y. Компилятор может выполнить банальное сложение двух заданных точек, но, чтобы их выполнить, нужно указать поведение: например, когда нужно решать по формуле, для этого и служит перегрузка операторов. При ней пользователь С# задает правильное поведение, которое ожидается от класса.
class MyPoint
{
int х, у,z// три координаты
public MyPoint() { х = у = z = 0; }
// Перегрузить бинарный оператор +.
public static MyPoint operator +(MyPoint op1, MyPoint op2)
{
MyPoint result = new MyPoint();
/* Сложить координаты двух точек и возвратить результат. */
result.х = op1.x + ор2.х; // Эти операторы выполняют
result.у = op1.y + ор2.у; // целочисленное сложение,
result.z = op1.z + op2.z; // сохраняя свое исходное назначение.
return result;
}
// Перегрузить бинарный оператор -.
public static MyPoint1 operator -(MyPoint1 op1, MyPoint1 op2)
{
MyPoint1 result = new MyPoint1();
/* Обратите внимание на порядок следования операндов:
op1 — левый операнд, а ор2 — правый операнд. */
result.х = op1.x — ор2.х; // Эти операторы
result.у = op1.y — ор2.у; // выполняют целочисленное
result.z = op1.z — op2.z; // вычитание
return result;
}
// Вывести координаты X, Y, Z.
public void Show()
{
Console.WriteLine(x + «, » + у + «, » + z);
}
}
Когда оператор перегружается, выполняет заданные поведение. Но его первоначальное назначение не меняется.
Перегружаемые операторы
Эти операторы можно перегрузить:
- Унарные операции +, -, !, ++, — true, false;
- Бинарные операции +, -, *, /, %, &, |, ,<<, >>;
- Операции сравнения должны быть перегружены парами ==, !=,<, >,<=, >=.
Данный код перегружает операцию сравнения. Выбирая значение из операндов, компилятор выполняет сравнение и возвращает истину или ложь.
// Перегрузить оператор >.
public static bool operator >(dot op1, dot op2)
{
if(op1.val > op2.val) return true;
else return false;
}
// Перегрузить оператор <.
public static bool operator <( dot op1, dot op2)
{
if(op1.val < op2.val) return true;
else return false;
}
Еще один пример для перегрузки операторов ==, -, *= приведен ниже. В качестве класса выберем «квадратное уравнение» с коэффициентами.
class KvadratUravn
{
public KvadratUravn ():this(0, 0, 0)
{
}
public KvadratUravn (double a_, double b_, double c_)
{
a=a_;
b=b_;
c=c_;
}
public double A { get { return a; } set { a = value; } }
public double B { get { return b; } set { b = value; } }
public double C { get { return c; } set { c = value; } }
public static bool operator ==( KvadratUravn raz, KvadratUravn dva)
{
return raz.a == dva.a &&
raz.b == dva.b &&
raz.c == dva.c;
}
public static bool operator !=( KvadratUravn raz, KvadratUravn dva)
{
return raz.a != dva.a &&
raz.b != dva.b &&
raz.c != dva.c;
}
public static KvadratUravn operator *( KvadratUravn raz, double dva)
{
return new KvadratUravn (raz.a * dva,
raz.b * dva,
raz.c * dva);
}
public static KvadratUravn operator -( KvadratUravn raz, double dva)
{
return new KvadratUravn (raz.a — dva,
raz.b — dva,
raz.c — dva);
}
public override string ToString()
{
return string.Format(«{0}, {1}, {2}», a, b, c);
}
private double a;
private double b;
private double c;
};
class Program
{
static void Main(string[] args)
{
KvadratUravn expr = new KvadratUravn (1, 2, 3);
Console.WriteLine(expr.ToString());
expr *= 5;
Console.WriteLine(expr.ToString());
expr -= 10;
Console.WriteLine(expr.ToString());
}
}
В следующем фрагменте кода программы приведен пример перегрузки логических операторов !, & и | для объектов класса Dot. Если один из точек координаты не равно нулю тогда программе покажет истину, а если все координаты равны нулю, тогда программа выдает значение ложь.
// Класс для хранения координат.
class dot
{
int х, у, z; // трехмерные координаты
public dot () { х = у = z = 0; }
public static bool operator |(dot op1, dot op2)
{
if( ((op1.x != 0) || (op1.у != 0) || (op1.z != 0)) | ((op2.x != 0) || (op2.у != 0) || (op2.z != 0)) )
return true;
else
return false;
}
// Перегрузить логический оператор &.
public static bool operator &(dot op1, dot op2)
{
if( ((op1.x != 0) && (op1.у != 0) && (op1.z != 0)) & ((op2.x != 0) && (op2.y != 0) && (op2.z != 0)) )
return true;
else
return false;
}
// Перегрузить логический оператор !.
public static bool operator !(dot op)
{
if((op.x != 0) || (op.y != 0) || (op.z != 0))
return false;
else return true;
}
// Вывести координаты X, Y, Z.
public void Show()
{
Console.WriteLine(x + «, » + у + «, » + z);
}
}
Перегрузка операторов C# заключение
Важно помнить, что на перегрузку операторов есть ограничения. Нельзя использовать оператор присваивания =. Кроме них есть операторы, которые в языке С# еще не определены. Так же, нельзя изменить количество операндов. Для бинарных операторов нельзя задавать три аргумента. Поскольку в его синтаксисе указан только два аргумента.
Чтобы создать легкий интерфейс, важно использовать перегрузки операторов. К тому же, учитывая их, вы упрощаете набранный код программы. Данное действие над операторами интересно тем, что пользователь сможет внедрить в программу свои правила и требования, контролируя функции операторов.
Также рекомендую прочитать статью Override C# | Переопределение методов C#. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.