25. Передача параметров по значению, (интеллектуальному) указателю или ссылке
25. Передача параметров по значению, (интеллектуальному) указателю или ссылке
Резюме
Вы должны четко уяснить разницу между входными, выходными параметрами и параметрами, предназначенными и для ввода, и для вывода информации, а также между передачей параметров по значению и по ссылке, и корректно их использовать.
Обсуждение
Правильный выбор способа передачи аргументов в функцию — по значению, ссылке или с использованием указателей — весьма необходимый навык, который поможет вам сделать ваш код максимально безопасным и эффективным.
Хотя эффективность не должна быть нашей главной целью (см. рекомендацию 8), при прочих равных условиях, включая понятность кода, мы не должны без крайней необходимости снижать его эффективность (см. рекомендацию 9).
Вам стоит следовать приведенным ниже рекомендациям при выборе способа передачи параметров. Вот рекомендации для входных параметров (которые передают информацию в функцию, но не возвращают ее).
• Всегда описывайте все указатели или ссылки на входные параметры как const.
• Предпочитайте передачу примитивных типов (например, char или float) и объектов-значений с недорогими операциями копирования (например, Point или Complex<float>) по значению.
• Входные аргументы прочих пользовательских типов лучше передавать как ссылки на const.
• Подумайте о передаче по значению вместо передачи по ссылке, если функция требует создания копии аргумента. Концептуально передача по значению эквивалентна передаче ссылки на константный объект и выполнение копирования, и может помочь компилятору в выполнении оптимизации по устранению временных переменных.
Далее приведены рекомендации для выходных параметров (а также параметров для одновременного ввода и вывода информации).
• Если аргумент необязателен, лучше передать его как (интеллектуальный) указатель (что позволит вызывающей функции передать нулевое значение как указание, что аргумент отсутствует); тот же совет применим и в случае, если функция сохраняет копию указателя или как-то иначе работает с принадлежностью аргумента.
• Если аргумент обязательный и функция не сохраняет указатель на него или каким-то иным образом влияет на его принадлежность, то такой аргумент лучше передавать по ссылке. Это указывает, что наличие данного аргумента обязательно, и заставляет вызывающую функцию отвечать за предоставление корректного объекта.
Не используйте функции с переменным количеством аргументов (см. рекомендацию 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