Разница между ссылкой и константной ссылкой в ​​качестве параметра функции? - PullRequest
5 голосов
/ 12 ноября 2009

Вот простой фрагмент кода C ++:

A foo(){
  A a; // create a local A object
  return a;
}

void bar(const A & a_r){

}

bar(foo());

Почему аргумент функциональной панели должен быть константной ссылкой, а не просто ссылкой?

Edit1: я знаю, что это ссылка, чтобы избежать копирования накладных расходов. и const только для чтения. Но здесь я должен сделать это ссылкой на const, иначе, если я удалю «const», g ++ выдаст мне ошибку.

Edit2: я предполагаю, что возвращаемый объект foo () является временным объектом, и ему не разрешено изменять значение временного объекта?

Ответы [ 4 ]

5 голосов
/ 12 ноября 2009

Без сообщения об ошибке я не совсем уверен, на что может пожаловаться компилятор, но могу объяснить причину логически:

В строке:

bar(foo()); 

Возвращаемое значение foo () является временным A; он создается вызовом foo (), а затем уничтожается, как только возвращается bar (). Выполнение неконстантной операции (то есть операции, которая изменяет временную A) не имеет смысла, так как сразу после этого уничтожается объект A.

Глядя немного больше, это виртуальная копия этого вопроса:

Почему неконстантная ссылка не может привязываться к временному объекту?

который имеет отличный ответ.

0 голосов
/ 12 ноября 2009

Компилятор ищет bar(const foo&), потому что вы передаете const reference to foo в bar в bar(foo()) - это потому, что вы передаете ссылку на временную переменную, которая не будет существовать, когда bar возвращает .

Не существует варианта использования, в котором имеет смысл изменить foo внутри bar через ссылку, потому что он не будет существовать, как только вы вернетесь из bar ().

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

0 голосов
/ 12 ноября 2009

Почему аргумент панели функций должна быть константной ссылкой, а не просто ссылка?

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

  • Задание константы параметра гарантирует, что компилятор выдаст предупреждение при попытке изменить объект.
  • Передача параметра в качестве ссылки не создаст копию объекта, и, следовательно, эффективность будет достигнута.
0 голосов
/ 12 ноября 2009

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

void bar(A&);   
A x = foo();
bar(x);
if (x.member) {...} else {...}

и

void bar(A const&);   
bar(foo());
if (//x? we don't have any x! We can't branch here!

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...