Перегруженные операторы - потенциально превосходные способы делать определенные вещи, но их ужасно легко злоупотреблять.
Перегрузка операторов <<
и >>
позволяет легко расширять потоки C ++ как в новых видах потоков, так и в новых объектах для ввода-вывода, и в обоих случаях. Перегрузка ->
делает умные указатели практически заменой указателей C ++. Перегруженные операторы позволяют иметь оператор конкатенации строк и создавать новые виды чисел, которые синтаксически аналогичны int
s. Их наличие позволяет делать в библиотеках такие вещи, которые требуют изменения уровня языка в других языках.
У них есть свои ограничения. Нет оператора, подходящего для возведения в степень. Существует только один оператор умножения, а в некоторых случаях есть несколько способов умножения (например, для трехмерных векторов есть по крайней мере точки и перекрестные произведения). Операторы &&
, ||
и запятая не могут реплицировать свои встроенные функции, поскольку они не могут иметь оценки короткого замыкания и точки последовательности.
И, конечно, ими можно злоупотреблять. Например, нет требования к языку, что арифметические операторы должны работать так же, как арифметические. Я видел ужасные вещи, сделанные в попытке придумать нотацию SQL, которую кто-то считал интуитивно понятной. В плохо написанной программе на C ++ невозможно знать, что, скажем, a = x * y;
делает, поскольку это a.operator=(x.operator*(y));
, или, может быть, a.operator=(operator*(x, y));
или что-то еще, и операторные функции могут быть написаны так, чтобы делать что угодно.
Намерение Бьярна Страуструпа при разработке C ++ заключалось в том, чтобы включить полезные функции независимо от возможности злоупотребления, тогда как намерение Джеймса Гослинга при разработке Java состояло в том, чтобы исключить чрезмерно злоупотребляемые функции, даже если они были несколько полезны. Мне не ясно, является ли любая из этих философий правильной или неправильной, но они разные.
Java была разработана, чтобы избежать ситуаций, в которых обычно требуются некоторые функции C ++, такие как перегрузка операторов, множественное наследование и вычитание типов во время выполнения, поэтому их часто не пропускают. Хорошо это или плохо, или ни то, ни другое я не знаю.
Что касается обучения студентов, скажите им не перегружать самих операторов (за исключением определенных условий, таких как функторы и оператор присваивания), но укажите, как в библиотеке используются перегруженные операторы. Я бы не стал доверять любому студенту C ++, который сделал бы их правильно, и если они будут в состоянии сделать это, они могут и изучат это самостоятельно. Они будут знать, что это сложно, потому что вы запретили это в классе. Некоторые из тех, которым я бы никогда не доверял ничего более сложного, чем оператор for
, узнают, как перегрузить операторы, и все равно это сделают, но это жизнь.