Подтвердить что ты не робот

Когда использовать const и const ссылку в функции args

При написании функции С++, в которой есть аргументы, которые передаются ей, из моего понимания const всегда следует использовать, если вы можете гарантировать, что объект не будет изменен или указатель const, если указатель не будет изменен.

Когда еще эта практика рекомендуется?

Когда вы будете использовать константную ссылку и какие преимущества перед ее прохождением через указатель, например?

Как насчет этого void MyObject::Somefunc(const std::string& mystring) Какой смысл иметь строку const, если строка на самом деле является неизменяемым объектом?

4b9b3361

Ответ 1

Вопрос о том, следует ли добавлять const, - это неправильный вопрос, к сожалению.

Сравните non-const ref с передачей указателя не-const

void modifies(T &param);
void modifies(T *param);

Этот случай в основном касается стиля: вы хотите, чтобы вызов выглядел как call(obj) или call(&obj)? Однако есть две точки, где разница имеет значение. Если вы хотите передать null, вы должны использовать указатель. И если вы перегружаете операторов, вы не можете использовать указатель вместо этого.

Сравнить const ref to по значению

void doesnt_modify(T const &param);
void doesnt_modify(T param);

Это интересный случай. Эмпирическое правило "дешево копировать" передается по значению - обычно это небольшие типы (но не всегда), в то время как другие передаются константой ref. Однако, если вам нужно сделать копию внутри своей функции независимо, вы должны пройти по значению. (Да, это предоставляет немного деталей реализации. C'est le С++.)

Сравнение указателя const с немодифицирующей плюс перегрузкой

void optional(T const *param=0);
// vs
void optional();
void optional(T const &param); // or optional(T param)

Это связано с немодулируемым случаем выше, за исключением того, что параметр передачи является необязательным. Здесь существует наименьшая разница между всеми тремя ситуациями, поэтому выберите, какая из них сделает вашу жизнь проще. Конечно, значение по умолчанию для указателя, отличного от const, зависит от вас.

Константа по значению представляет собой деталь реализации

void f(T);
void f(T 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

Ответ 2

Общее правило: используйте const, когда это возможно, и при необходимости опустите его. const может позволить компилятору оптимизировать и помогает вашим коллегам понять, как ваш код предназначен для использования (и компилятор поймает возможное неправильное использование).

Что касается вашего примера, строки не являются неизменяемыми в С++. Если вы передаете ссылку не на const на строку для функции, функция может ее изменить. С++ не имеет понятия неизменяемости, встроенного в язык, вы можете эмулировать его только с помощью инкапсуляции и const (который никогда не будет пуленепробивным, хотя).

После обсуждения комментария @Eamons и чтения некоторых вещей, я согласен, что оптимизация не является основной причиной использования const. Основная причина - иметь правильный код.

Ответ 3

Вопросы основаны на некоторых неправильных предположениях, поэтому не имеют смысла.

std::string не моделирует неизменяемые строковые значения. Он моделирует изменяемые значения.

Нет такой вещи, как "ссылка на константу". Есть ссылки на объекты const. Различие является тонким, но важным.

Верхний уровень const для аргумента функции имеет смысл только для реализации функции, а не для чистого объявления (где он не учитывается компилятором). Он ничего не сообщает вызывающему. Это лишь ограничение на реализацию. Например. int const довольно бессмысленна как тип аргумента в чистом объявлении функции. Однако const в std::string const& не является верхним уровнем.

Передача по ссылке const позволяет избежать неэффективного копирования данных. В общем случае для передачи данных в функцию вы передаете мелкие элементы (например, int) по значению и потенциально более крупные элементы по ссылке на const. В машинный код ссылка на const может быть оптимизирована или может быть реализована как указатель. Например, в 32-битной Windows a int составляет 4 байта, а указатель - 4 байта. Таким образом, тип аргумента int const& не уменьшил бы копирование данных, но мог бы с простым программистом ввести дополнительную косвенность, что означает небольшую неэффективность - следовательно, небольшое/большое различие.

Приветствия и hth.,

Ответ 4

Основное преимущество ссылки const над указателем const заключается в следующем: его ясно, что параметр требуется и не может быть NULL. И наоборот, если я вижу указатель на const, я сразу же предполагаю, что причина не в том, что этот параметр может быть NULL.