Правила программирования на Си и Си++



         

145. Операция — это сокращение (без сюрпризов)


Операция — это не произвольный значок, означающий все, что вы ни пожелаете. Это аббревиатура англоязычного слова. Например, символ +

значит "прибавить", поэтому вы не должны заставлять перегруженный operator+()

делать что-нибудь еще. Хотя здесь все ясно (вы можете определить a + b для вычитания b из a, но не должны делать этого), я на самом деле веду речь о проблемах более творческого характера.

Вы можете благоразумно доказывать, что, когда выполняете конкатенацию, то "прибавляете" одну строку к концу другой, поэтому перегрузка + для конкатенации может быть приемлема. Вы также можете доказывать, что разумно использовать операции сравнения для лексикографического упорядочивания в классе string, поэтому перегрузка операций <, == и т.д. также вероятно пойдет. Вы не сможете аргументировано доказать, что – или * имеют какой-нибудь смысл по отношению к строкам.

Другим хорошим примером того, как нельзя действовать, является интерфейс Си++ iostream. Использование сдвига (<<) для обозначения "вывод" является нелепым. Ваши функции вывода в Си назывались printf(), а не shiftf(). Я понимаю, что Страуструп выбрал сдвиг, потому что он сходен с механизмом перенаправления ввода/вывода различных оболочек UNIX, но этот довод на самом деле не выдерживает проверки. Страуструп исходил из того, что все программисты на Си++ понимают перенаправление в стиле UNIX, но эта концепция отсутствует в некоторых операционных системах — например, в Microsoft Windows. К тому же, для того, чтобы аналогия была полной, операция >

должна быть перегружена для выполнения операции затирания, а >>

добавления в конец. Тем не менее, тот факт, что > и >>

имеют различный приоритет, делает реализацию такого поведения затруднительной. Дело осложняется тем, что операторы сдвига имеют неправильный уровень приоритета. Оператор типа cout

<< x += 1 не будет работать так, как вы ожидаете, потому что у <<

более высокий приоритет, чем у +=, поэтому оператор интерпретируется как (cout << x) += 1, что неверно. Си++ нуждается в расширяемости, обеспечиваемой системой iostream, но он вынужден добиваться ее за счет введения операторов "ввода" и "вывода", имеющих низший приоритет по отношению к любому оператору языка.




Содержание  Назад  Вперед