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

Параметры функции как ссылка на конструкцию

Есть ли причина не отправлять параметр как const &, а не по значению, когда он не будет изменен и копия не будет сделана? Я понимаю, что параметр const по значению такой же, как без const (и не будет перегружать друг друга), поэтому он все равно будет скопирован.

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

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

4b9b3361

Ответ 1

Как правило, нет ничего плохого в передаче аргументов только для чтения в качестве констант-ссылок и для любого класса тяжеловесного класса, который, безусловно, наиболее эффективный способ сделать это.

Возможно, вы захотите рассмотреть возможность переноса примитивных типов путем копирования, потому что там, где ссылка может фактически налагать больше затрат, чем просто копирование (например, копирование будет просто вписываться в один регистр, тогда как ссылка может быть реализована с помощью указателя и т.д..).

Кроме того, вы можете передать std::shared_ptr и итераторы по значению, они сделаны для этого.

Что касается передачи по const-значению, то реализация. Используйте его так:

// Declaration:
int foo(int n, double d); // No "const"! Constness is not part of the interface.

// Definition
int foo(int n, const double d) // implementation detail
{
  while (n--) { if (d > n) return n; }
}

В реализации вы можете или не можете напрямую использовать переменные аргументов и изменять их (например, n), или вы можете рассматривать их как доступные для чтения (например, d), и вы объявляете аргументы соответствующим образом.

Ответ 2

Как правило, вы должны передавать примитивные типы, такие как указатели, int, bool, float, double значением (не const) и типами объектов, такими как std::string, std::vector и пользовательские классы по ссылке (const). В качестве исключения из этого правила существуют легкие классы, специально предназначенные для передачи по значению, например интеллектуальные указатели.

Передача значения значением const, например. void foo(const double bar), не имеет смысла - почему не разрешается foo изменять свою копию bar? Объявление параметра как const бесполезно здесь.

Передача примитивов по ссылке не имеет особого смысла. За кулисами, когда параметр передается по ссылке, указатель передается по значению. Копирование указателя обычно так же дорого, как копирование примитивного типа (например, int), а параметры типа const int& выглядят довольно странно для большинства программистов на С++.