Спрашивать, добавлять ли const - это неправильный вопрос, , к сожалению.
Сравнить неконстантную ссылку с передачей неконстантного указателя
void modifies(T ¶m);
void modifies(T *param);
Это дело в основном о стиле: хотите, чтобы звонок выглядел как call(obj)
или call(&obj)
? Однако есть два момента, где разница имеет значение. Если вы хотите иметь возможность передавать значение NULL, вы должны использовать указатель. А если вы перегружаете операторы, вы не можете вместо этого использовать указатель.
Сравните const ref со значением
void doesnt_modify(T const ¶m);
void doesnt_modify(T param);
Это интересный случай. Практическое правило гласит, что типы «дешевого копирования» передаются по значению - обычно это небольшие типы (но не всегда), в то время как другие передаются по const ref. Тем не менее, если вам нужно сделать копию внутри вашей функции независимо, вы должны передать значение . (Да, это раскрывает некоторые детали реализации. C'est le C ++. )
Сравнить константный указатель с немодифицируемой плюс перегрузкой
void optional(T const *param=0);
// vs
void optional();
void optional(T const ¶m); // or optional(T param)
Это относится к неизменяющему случаю, описанному выше, за исключением того, что передача параметра является необязательной. Здесь наименьшая разница между всеми тремя ситуациями, так что выбирайте, что облегчит вашу жизнь. Конечно, значение по умолчанию для неконстантного указателя зависит от вас.
Константа по значению является подробностью реализации
void f(T);
void f(T const);
Эти объявления на самом деле являются точно такой же функцией! При передаче по значению const является просто деталью реализации. Попробуйте:
void f(int);
void f(int const) {/*implements above function, not an overload*/}
typedef void C(int const);
typedef void NC(int);
NC *nc = &f; // nc is a function pointer
C *c = nc; // C and NC are identical types