Стандарты программирования на С++. 101 правило и рекомендация
Шрифт:
[Lakos96] §3.2 • [Stroustrup00] §9.2.3 • [Sutter00] §26-30 • [Vandevoorde03] §9-10
24. Используйте только внутреннюю, но не внешнюю защиту директивы
Предотвращайте непреднамеренное множественное включение ваших заголовочных файлов директивой
Каждый заголовочный
Обратите внимание на следующие правила при определении защиты включения.
• Используйте для защиты уникальные имена. Убедитесь, что вы используете имена, уникальные, по крайней мере, в пределах вашего приложения. Выше мы использовали одно распространенное соглашение для используемых в защите имен; имена для защиты могут включать имя приложения, а некоторые инструменты генерируют имена для защиты, содержащие случайные числа.
• Не пытайтесь хитрить. Не размещайте никакого кода или комментариев до и после защищенной части, и следуйте показанной выше стандартной форме защиты. Современные препроцессоры могут обнаружить защиту, но могут оказаться малоинтеллектуальными и ожидать кода защиты строго в начале и в конце заголовочных файлов.
Избегайте использования устаревшей внешней защиты директивы
Внешняя защита утомительна, устарела для современных компиляторов и ненадежна из-за необходимости согласования имен для защиты.
В очень редких случаях заголовочный файл может быть предназначен для многократного включения.
[C++03, §2.1] • [Stroustrup00] §9.3.3
Функции и операторы
Если ваша процедура имеет десять параметров — вероятно, вы где-то ошиблись.
Функции, включая перегруженные операторы, представляют собой фундаментальные единицы работы. Как вы увидите позже в разделе "Обработка ошибок и исключения" (в частности, в рекомендации 70), это непосредственно влияет на наши рассуждения о корректности и безопасности кода.
Но давайте сначала рассмотрим некоторые фундаментальные вопросы написания функций, в том числе операторов. В частности, мы обратим особое внимание на их параметры, семантику и перегрузку.
В этом разделе наиболее важной нам представляется рекомендация 26 — "Сохраняйте естественную семантику перегруженных
25. Передача параметров по значению, (интеллектуальному) указателю или ссылке
Вы должны четко уяснить разницу между входными, выходными параметрами и параметрами, предназначенными и для ввода, и для вывода информации, а также между передачей параметров по значению и по ссылке, и корректно их использовать.
Правильный выбор способа передачи аргументов в функцию — по значению, ссылке или с использованием указателей — весьма необходимый навык, который поможет вам сделать ваш код максимально безопасным и эффективным.
Хотя эффективность не должна быть нашей главной целью (см. рекомендацию 8), при прочих равных условиях, включая понятность кода, мы не должны без крайней необходимости снижать его эффективность (см. рекомендацию 9).
Вам стоит следовать приведенным ниже рекомендациям при выборе способа передачи параметров. Вот рекомендации для входных параметров (которые передают информацию в функцию, но не возвращают ее).
• Всегда описывайте все указатели или ссылки на входные параметры как
• Предпочитайте передачу примитивных типов (например,
• Входные аргументы прочих пользовательских типов лучше передавать как ссылки на
• Подумайте о передаче по значению вместо передачи по ссылке, если функция требует создания копии аргумента. Концептуально передача по значению эквивалентна передаче ссылки на константный объект и выполнение копирования, и может помочь компилятору в выполнении оптимизации по устранению временных переменных.
Далее приведены рекомендации для выходных параметров (а также параметров для одновременного ввода и вывода информации).
• Если аргумент необязателен, лучше передать его как (интеллектуальный) указатель (что позволит вызывающей функции передать нулевое значение как указание, что аргумент отсутствует); тот же совет применим и в случае, если функция сохраняет копию указателя или как-то иначе работает с принадлежностью аргумента.
• Если аргумент обязательный и функция не сохраняет указатель на него или каким-то иным образом влияет на его принадлежность, то такой аргумент лучше передавать по ссылке. Это указывает, что наличие данного аргумента обязательно, и заставляет вызывающую функцию отвечать за предоставление корректного объекта.
Не используйте функции с переменным количеством аргументов (см. рекомендацию 98).
[Alexandrescu03a] • [Cline99] §2.10-11, 14.02-12, 32.08 • [Dewhurst03] §57 • [Koenig97] §4 • [Lakos96] §9.1.11-12 • [McConnell93] §5.7 • [Meyers97] §21-22 • [Stroustrup94] §11.4.4 • [Stroustrup00] §5.5, §11.6, §16.3.4 • [Sutter00] §6, §46
26. Сохраняйте естественную семантику перегруженных операторов