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

Зачем переходить по ссылке const вместо значения?

Из того, что я понимаю: когда вы проходите по значению, функция создает локальную копию переданного аргумента и использует это; когда функция заканчивается, она выходит за рамки. Когда вы передаете ссылку const, функция использует ссылку на переданный аргумент, который не может быть изменен. Однако я не понимаю, почему один выбирал один за другим, за исключением ситуации, когда аргумент должен быть изменен и возвращен. Если у вас была функция void, в которой ничего не возвращается, зачем выбирать один за другим?

РЕДАКТИРОВАТЬ: Таким образом, в основном передача константой const позволяет избежать копирования объекта. Так в каких ситуациях копировать объект хорошо? Я имею в виду, почему бы не просто использовать константные ссылки все время, если он постоянно оптимизирует производительность?

4b9b3361

Ответ 1

Есть два основных соображения. Один из них - это расход копирования переданного объекта, а второй - предположения, которые компилятор может сделать, когда объект является локальным объектом.

например. В первом виде в теле f нельзя предположить, что a и b не ссылаются на один и тот же объект; поэтому значение a должно быть перечитано после любой записи на b, на всякий случай. Во второй форме a нельзя изменить с помощью записи в b, поскольку она является локальной для функции, поэтому эти повторные чтения не нужны.

void f(const Obj& a, Obj& b)
{
    // a and b could reference the same object
}

void f(Obj a, Obj& b)
{
    // a is local, b cannot be a reference to a
}

Например: В первом примере компилятор может предположить, что значение локального объекта не изменяется при выполнении несвязанного вызова. Без информации о h компилятор может не знать, не изменяется ли объект, который эта функция ссылается на (через ссылочный параметр), на h. Например, этот объект может быть частью глобального состояния, которое изменяется на h.

void g(const Obj& a)
{
    // ...
    h(); // the value of a might change
    // ...
}

void g(Obj a)
{
    // ...
    h(); // the value of a is unlikely to change
    // ...
}

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

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

Ответ 2

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

Обычно основные типы (int, double,...) передаются по значению, а типы классов передаются по ссылке const.

Однако может быть исключения, где может быть полезно значение pass-by-value для классов.

Ответ 3

Создание копии объекта может в значительной степени повлиять на производительность. Рассмотрим функцию, аргумент которой будет std::vector<long>, и вы хотите передать вектор с 1 миллионом элементов. В этом случае вы захотите использовать константную ссылку для передачи по значению. В this SO question вы можете найти простое общее правило для своего вопроса.

Ответ 4

Иногда создание копии объекта может быть дорогостоящим, и поэтому ссылка "pass-by-const-reference" позволяет избежать этой копии. В противном случае я бы сказал, что вам нужно просто передать значение, если это то, что семантически требуется.

Ответ 5

Чтобы избежать ненужной копии, тем самым повышая производительность.

Ответ 6

Передача аргумента по значению имеет накладные расходы на копию объекта, передаваемого функции.

Возможно, объект не копируется и ваши ограничения ограничены.

Ответ 7

Из-за преимуществ производительности вы получите. Допустим, у вас большой объект (с точки зрения размера в байтах). Теперь, если вы передаете этот объект по значению функции, необходимо создать ненужную копию из этого, однако вы можете получить тот же эффект, передав ссылку const этому объекту без создания копии. Поскольку ссылка обычно хранится как указатель под капотами, стоимость передачи ссылки равна sizeof(pointer).

Ответ 8

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