Перегрузка операторов¶
Для типов структур и классов возможно перегрузить ряд операторов и операций. Перегруженный оператор это просто функция внутри класса и структуры, имеющая специальное имя и выполняющая ряд требований. У всех перегруженных операторов и операций тип одного из аргументов должен быть той структуры или того класса, в которой объявлены операция или оператор.
Объявляется перегруженный оператор с использованием ключевого слова op
и имени оператора после него.
struct Int
{
i32 x;
op+( Int& l, Int& r ) : Int // Перегруженный бинарный оператор
{
var Int i{ .x= l.x + r.x };
return i;
}
op-( Int& a ) : Int // Перегруженный префиксный унарный оператор
{
var Int b{ .x= -a.x };
return b;
}
op++( mut this ) // Перегруженная унарная операция
{
++x;
}
op[]( this, i32 y ) : i32 // Перегруженный постфиксный оператор
{
return x * y;
}
}
fn Foo()
{
var Int mut a{ .x= 42 }, b{ .x= 666 };
++a;
auto ab= a + b;
auto minus_b= -b;
var i32 r= a[5];
}
Перегружаемые операторы и операции:
Оператор |
тип |
Число аргументов |
Возвращаемый результат |
---|---|---|---|
|
префиксный оператор |
1 |
любой |
|
префиксный оператор |
1 |
любой |
|
префиксный оператор |
1 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
любой |
|
бинарный оператор |
2 |
|
|
бинарный оператор |
2 |
|
|
постфиксный оператор |
2 |
любой |
|
постфиксный оператор |
1 и более |
любой |
|
унарная операция |
1 |
|
|
унарная операция |
1 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
|
бинарная операция |
2 |
|
Ряд перегруженных операторов вызываются особым образом.
Для ==
и !=
вызывается перегруженный оператор ==
.
Не существует отдельной перегрузки оператора !=
.
Для получения результата !=
результат вызова ==
инвертируется.
Для операторов упорядочивающего сравнения (<
, <=
, >
, >=
) вызывается перегруженный оператор <=>
.
Результат его вызова сравнивается с нулём для получения конечного результата.
Перегруженному оператору <=>
не обязательно возвращать строго -1 или +1 для индикации отношения больше/меньше, важен лишь знак результата.
Постфиксные операторы¶
Особое место занимают постфиксные операторы. У всех них есть требование, чтобы тип первого аргумента был тот же, что у типа структуры или класса, где объявлен этот оператор.
Оператор индексирования []
позволяет обращаться по индексу к структуре или классу, как будто это массив. При этом тип индекса может быть любым.
Это позволяет, например, организовать ассоциативные контейнеры с доступом по ключу с использованием данного оператора.
Оператор вызова ()
позволяет обращаться с структурой или классом подобно функции. Это позволяет, например, реализовывать функциональные объекты.