Большинство операторов в C++ просто используют свои операнды для вычисления возвращаемого значения. Например, -5
возвращает значение -5
, а 2 + 3
возвращает значение 5
. Есть несколько операторов, которые не выдают возвращаемых значений (например, delete
и throw
). О том, что они делают, мы расскажем позже.
Некоторые операторы обладают дополнительным поведением. Оператор (или функция), который имеет некоторый наблюдаемый эффект помимо получения возвращаемого значения, называется оператором с побочным эффектом. Например, при вычислении x = 5
оператор присваивания имеет побочный эффект присвоения переменной x
значения 5
. Измененное значение x можно наблюдать (например, распечатав значение x
) даже после завершения выполнения оператора. std::cout << 5
имеет побочный эффект печати 5
на консоль. Мы можем наблюдать тот факт, что 5
было выведено на консоль даже после завершения выполнения std::cout << 5
.
Операторы с побочными эффектами обычно вызываются для поведения побочного эффекта, а не для возвращаемого значения (если таковое имеется), которое этот оператор производит.
Обозначение
В обыденной речи термин "побочный эффект" обычно используется для обозначения вторичного (часто негативного или неожиданного) результата какого-то другого действия (например, приема лекарства). Например, распространенным побочным эффектом приема пероральных антибиотиков является диарея. В C++ термин "побочный эффект" имеет другое значение: это наблюдаемый эффект оператора или функции, помимо получения возвращаемого значения. Поскольку присваивание имеет наблюдаемый эффект изменения значения объекта, это считается побочным эффектом. Некоторые операторы (например, оператор присваивания) мы используем в основном из-за их побочных эффектов. В таких случаях побочный эффект выгоден и предсказуем (а возвращаемое значение часто бывает случайным).
Дополнительно
Для операторов, которые мы вызываем в первую очередь ради их возвращаемых значений (например, operator+ или operator*), обычно очевидно, какими будут возвращаемые значения (например, сумма или произведение операндов).
Для операторов, которые мы вызываем в первую очередь ради их побочных эффектов (например, operator= или operator<<), не всегда очевидно, какие возвращаемые значения они производят (если они вообще есть). Например, какое возвращаемое значение вы ожидаете получить от x = 5
?
И operator=, и operator<< (когда они используются для вывода значений на консоль) возвращают свой левый операнд. Таким образом, x = 5
возвращает x
, а std::cout << 5
возвращает std::cout
. Это сделано для того, чтобы эти операторы можно было объединять в цепочку.
Например, x = y = 5
оценивается как x = (y = 5)
. Сначала y = 5
присваивает y
значение 5
. Затем эта операция возвращает y
, которое можно присвоить x
.
std::cout << "Hello " << "world!"
эквивалентно (std::cout << "Hello ") << "world!". Сначала мы выводим "Hello "
на консоль. Эта операция возвращает std::cout
, который затем может быть использован для печати "world!"
на консоли.
Демонстрация побочных эффектов: