Присвоение (должен быть функцией-членом) | |
+ | Сложение |
- -= | Вычитание |
* *= | Умножение и разыменование |
/ /= | Деление |
% %= | Остаток от деления |
++ | Инкремент |
-- | Декремент |
^ ^= | Битовое исключающее ИЛИ |
~ | Битовое дополнение |
& &= | Битовое И |
| |= | Битовое ИЛИ |
<< <<= | Сдвиг влево |
>> >>= | Сдвиг вправо |
Для большинства операторов из табл. 8.1 существует две лексемы: первая — это версия оператора, используемая обычным образом, т.е. 1+2
, а вторая версия — это версия, которая также присваивает результат операции переменной, т. е. x+=5
. Заметьте, что операторы инкремента и декремент ++
и --
описываются в рецепте 8.13.
Реализация всех арифметических операторов и оператора присвоения очень похожа, за исключением оператора присвоения, который не может быть отдельной функцией (т.е. он должен быть методом).
Наиболее популярным при перегрузке является оператор сложения — благодаря тому что он может использоваться в отличных от математических контекстах, таких как объединение двух строк, так что давайте вначале рассмотрим именно его. Он складывает правый аргумент с левым и присваивает результирующее значение левому аргументу, как в выражении.
int i = 0;
i += 5;
После выполнения второй строки int i
изменяется и содержит значение 5. Аналогично, если посмотреть на пример 8.15, следует ожидать такого же поведения от этих строк.
Balance checking(500.00), savings(23.91);
checking += 50;
Это означает, что следует ожидать, что после использования оператора +=
значение checking
будет увеличено на 50. Именно это происходит при использовании реализации из примера 8.15. Посмотрите на определение функции для оператора +=
.
Balance& operator+=(double other) {
val_ += other;
return(*this);
}
Для оператора присвоения список параметров — это то, что будет указано в операторе в его правой части. В данном случае используется целое число. Тело этой функции тривиально: все, что здесь делается, — это добавление аргумента к частной переменной-члену. Когда эта работа сделана, возвращается *this
. Возвращаемым значением из арифметических операторов и операторов присвоения должно быть *this
, что позволяет использовать их в выражениях, когда их результаты будут входом для чего-то еще. Например, представьте, что operator+= объявлен вот так.
void operator+=(double other) { // Не делайте так
val += other;
}
Затем кто-то захочет использовать этот оператор для экземпляра класса и передать результат в другую функцию.
Balance moneyMarket(1000.00);
// ...
updateGeneralLeager(moneyMarket += deposit); // He скомпилируется
Это приведет к проблеме, так как Balance::operator+=
возвращает void
, а функция типа updateGeneralLedger
ожидает получить объект типа Balance. Если из арифметических операторов и оператора присвоения возвращать текущий объект, то этой проблемы не возникнет. Однако это верно не для всех операторов. Другие операторы, типа оператора элемента массива []
или оператора отношения возвращают объекты, отличные от *this
, так что это правило верно только для арифметических операторов и операторов