Большинство операторов в 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!" на консоли.
Демонстрация побочных эффектов: