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



         

148. Перегруженные операции должны работать точно так же, как они работают в Си


Главной новой проблемой здесь являются адресные типы lvalue и rvalue. Выражения типа lvalue

легко описываются в терминах Си++: они являются просто ссылками. Компилятор Си, вычисляя выражение, выполняет операции по одной за раз в порядке, определяемом правилами сочетательности и старшинства операций. Каждый этап в вычислениях использует временную переменную, полученную при предыдущей операции. Некоторые операции генерируют "rvalue" —

действительные объекты, на самом деле содержащие значение. Другие операции создают "lvalue" —

ссылки на объекты. (Кстати, "l" и "r" используются потому, что в выражении l=r

слева от =

генерируется тип lvalue. Справа образуется тип rvalue).

Вы можете сократить эффект неожиданности для своего читателя, заставив свои перегруженные операции-функции работать тождественно их эквивалентам на Си в пределах того, что они могут. Далее описано, как работают операции Си и как имитировать их поведение:

·

Операции присваивания (=, +=, -= и т.д.) и операции автоинкремента и автодекремента (++, --) требуют операндов типа lvalue для адресата — части, которая изменяется. Представьте ++ как эквивалент для +=1, чтобы понять, почему эта операция в той же категории, что и присваивание.

В перегруженных операциях функций-членов указатель this на самом деле является lvalue, поэтому здесь не о чем беспокоиться. На глобальном уровне левый операнд перегруженной бинарной операции присваивания (и единственный операнд перегруженной унарной операции присваивания) должен быть ссылкой.

·      Все другие операции могут иметь операнды как типа lvalue,

так и rvalue.

Используйте ссылку на объект типа const для всех операндов. (Вы могли бы передавать операторы по значению, но обычно это менее эффективно).

·      Имена переменных составного типа (массивов) создают типы rvalue —

временные переменные типа указателя на первый элемент, после инициализации на него и указывающие. Заметьте, что неверно представление о том, что вы не можете инкрементировать имя массива из-за того, что оно является константой. Вы не можете инкрементировать имя массива, потому что оно имеет тип rvalue, а все операции инкремента требуют операндов типа lvalue.




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