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

При использовании бинарных операторов в выражении участвуют два операнда. Примеры бинарных операторов: + (сложение), - (вычитание), * (умножение), / (деление), % (остаток от деления), & (двоичное И), | (двоичное ИЛИ), ^ (двоичное исключающее ИЛИ), << (сдвиг влево), >> (сдвиг вправо) и оператор «запятая». К бинарным операторам также относятся операторы сравнения: == (равно), != (не равно), < (меньше), > (больше), <= (меньше или равно), >= (больше или равно), && (логическое И) и || (логическое ИЛИ).

При перегрузке бинарных операторов через единственный параметр в «операторном» методе доступен операнд, расположенный от оператора справа, а указатель на сам объект, расположенный от оператора слева, передается неявным образом. Таким образом внутри метода ко всем членам класса можно обращаться напрямую или через указатель this. Дружественной и обычной функции передаются два параметра. Через первый параметр доступен операнд, расположенный от оператора слева, а через второй параметр доступен операнд, расположенный от оператора справа. Тип возвращаемого значения, а также внутренняя реализация зависят от предпочтений программиста. Обратите внимание на то, что в обычных выражениях при использовании бинарных операторов возвращается новое значение, а значения операндов внутри выражения не изменяются. Хотя это не правило, а лишь рекомендация. В качестве примера перегрузим операторы + и == (листинг 14.1).

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

#include <iostream>

class C {
   int x_;
public:
   C() { x_ = 0; }                   // Конструктор по умолчанию
   explicit C(int x) { x_ = x; }     // Обычный конструктор
   C(const C &c) { x_ = c.x_; }      // Конструктор копирования
   int getX() const { return x_; }

   C operator+(const C &obj);                   // obj1 + obj2
   C operator+(int x);                          // obj + целое число
   friend C operator+(int x, const C &obj);     // целое число + obj

   bool operator==(const C &obj);               // obj1 == obj2
   bool operator==(int x);                      // obj == целое число
   friend bool operator==(int x, const C &obj); // целое число == obj
};

int main() {
   C obj1(10), obj2(20), obj3;
   obj3 = obj1 + obj2;
   std::cout << obj3.getX() << std::endl;     // 30
   obj3 = obj3 + 50;
   std::cout << obj3.getX() << std::endl;     // 80
   obj2 = 20 + obj3;
   std::cout << obj2.getX() << std::endl;     // 100

   std::cout << std::boolalpha;
   std::cout << (obj1 == obj2) << std::endl;  // false
   std::cout << (obj1 == 10) << std::endl;    // true
   std::cout << (100 == obj2) << std::endl;   // true
   return 0;
}

C C::operator+(const C &obj) {          // obj1 + obj2
   C newobj;
   newobj.x_ = x_ + obj.x_;
   return newobj;
}
C C::operator+(int x) {                 // obj + целое число
   C newobj;
   newobj.x_ = x_ + x;
   return newobj;
}
C operator+(int x, const C &obj) {      // целое число + obj
   C newobj;
   newobj.x_ = obj.x_ + x;
   return newobj;
}
bool C::operator==(const C &obj) {      // obj1 == obj2
   return x_ == obj.x_;
}
bool C::operator==(int x) {             // obj == целое число
   return x_ == x;
}
bool operator==(int x, const C &obj) {  // целое число == obj
   return x == obj.x_;
}

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

C C::operator,(int x) {                // obj , целое число
   std::cout << "operator,(int x) "
             << x_ << " " << x << std::endl;
   return C(x_ + x);
}

Создадим объекты и применим оператор «запятая»:

C obj1(10), obj2;
obj2 = obj1, 20;                       // Приоритет оператора = выше!!!
std::cout << obj2.getX() << std::endl; // 10
obj2 = (obj1, 20);
std::cout << obj2.getX() << std::endl; // 30
obj2 = (obj1, 20, 5, 10);
std::cout << obj2.getX() << std::endl; // 45

Результат выполнения в окне консоли:

operator,(int x) 10 20
10
operator,(int x) 10 20
30
operator,(int x) 10 20
operator,(int x) 30 5
operator,(int x) 35 10
45

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов