C++: использование '.' оператор выражений и вызовов функций
Мне было интересно, если это хорошая практика, чтобы использовать оператор члена .
как это:
someVector = (segment.getFirst() - segment.getSecond()).normalize().normalCCW();
Просто сделал это, чтобы показать две разные вещи, которые мне интересно, а именно, если использовать (expressions).member/function()
а также foo.getBar().getmoreBar()
были в соответствии с духом удобочитаемости и ремонтопригодности. Во всем коде на С ++ и в книгах, из которых я узнал, я никогда не видел, чтобы он использовался таким образом, но его опьяняюще легко использовать как таковой. Не хочу развивать какие-либо вредные привычки, хотя.
Вероятно, более (или менее) важным, чем это, я также задавался вопросом, будут ли какие-либо приросты / потери производительности при его использовании таким образом, или непредвиденные ловушки, которые могут привести к ошибкам в программе.
Заранее спасибо!
8 ответов
или непредвиденные ловушки, которые привели бы к ошибкам в программе
Ну, возможные подводные камни были бы
Сложнее отлаживать. Вы не сможете просматривать результаты каждого вызова функции, поэтому, если один из них возвращает что-то неожиданное, вам нужно разбить его на более мелкие сегменты, чтобы увидеть, что происходит. Кроме того, любой вызов в цепочке может полностью потерпеть неудачу, поэтому, возможно, вам придется прервать его, чтобы выяснить, какой вызов не удался.
Труднее читать (иногда). Цепные вызовы функций могут затруднить чтение кода. Это зависит от ситуации, здесь нет строгих правил. Если выражение даже несколько сложное, это может усложнить понимание. У меня нет проблем с чтением вашего конкретного примера.
В конечном итоге все сводится к личным предпочтениям. Я не стремлюсь вписаться как можно больше в одну строку, и я был достаточно укушен, цепляясь там, где мне не следует, что я склонен немного разбить вещи. Тем не менее, для простых выражений, которые вряд ли потерпят неудачу, цепочка это хорошо.
Да, это вполне приемлемо и фактически было бы совершенно нечитаемым во многих контекстах, если бы вы этого НЕ делали.
Это называется метод цепочки.
МОЖЕТ быть некоторый прирост производительности, поскольку вы не создаете временные переменные. Но любой компетентный компилятор все равно его оптимизирует.
someVector = (segment.getFirst() - segment.getSecond()).normalize().normalCCW();
Не ответ на ваш вопрос, но я должен сказать вам, что поведение выражения (segment.getFirst() - segment.getSecond())
не является четко определенным в соответствии со стандартом C++. Порядок, в котором оценивается каждый операнд, не определяется Стандартом!
Кроме того, см. Эту связанную тему: хорошо ли определен этот код?
Совершенно правильно использовать его так, как вы показали. Он используется в идиоме именованных параметров, описанных в C++ faq lite, например.
Одной из причин, по которой он не всегда используется, является необходимость сохранять промежуточный результат по соображениям производительности (если нормализация требует больших затрат и вам нужно использовать ее более одного раза, лучше сохранить результат в переменной) или удобочитаемости.
my2c
Использование переменной для хранения промежуточных результатов может иногда улучшить читабельность, особенно если вы используете правильные имена переменных. Чрезмерное сцепление может затруднить понимание происходящего. Вы должны использовать свое суждение, чтобы решить, стоит ли разрывать цепочки, используя переменные. Приведенный выше пример не является чрезмерным для меня. Производительность не должна сильно отличаться, если вы включите оптимизацию.
Это зависит от того, что вы делаете.
Для удобства чтения вы должны попытаться использовать промежуточные переменные.
Присвойте результаты вычислений указателям, а затем используйте их.
Я предполагаю, что то, что вы делаете, менее читабельно, однако, с другой стороны, слишком много временных переменных также могут стать нечитаемыми.
Что касается производительности, я уверен, что при создании временных переменных есть небольшие издержки, но компилятор может оптимизировать это.
Нет большой проблемы с его использованием таким образом - некоторые API значительно выигрывают от цепочки методов. Плюс вводить переменную в заблуждение, а затем использовать ее только один раз. Когда кто-то читает следующую строку, ему не нужно думать обо всех тех переменных, которые вы сейчас не сохранили.