Какая польза от цитирования ссылок const на примитивные типы?

В проекте, который я поддерживаю, я вижу такой код для простых методов get/set

const int & MyClass::getFoo() { return m_foo; }

void MyClass::setFoo(const int & foo) { m_foo = foo; }

Какой смысл делать это вместо следующего?

int MyClass::getFoo() { return m_foo; }  // Removed 'const' and '&' 

void MyClass::setFoo(const int foo) { m_foo = foo; }  // Removed '&'

Передача ссылки на примитивный тип должна требовать того же (или большего) усилия, как передача самого значения типа, правильно?
Это всего лишь число в конце концов...
Это просто попытка микро-оптимизации или есть ли настоящая выгода?

Ответы

Ответ 1

Разница в том, что если вы сами получите этот результат в ссылку, вы можете отслеживать изменения целочисленной переменной-члена в своем имени переменной без вызова функции.

const &int x = myObject.getFoo();
cout<<x<<endl;
//...
cout<<x<<endl;//x might have changed

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

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

void test1(int x)
{
  cout<<x<<endl;//prints 1
}

void test2(const int &x)
{
  cout<<x<<endl;//prints 1 or something else possibly, another thread could have changed x
}

int main(int argc, char**argv)
{
  int x = 1;
  test1(x);
  //...
  test2(x);
  return 0;
}

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

Ответ 2

Для меня передача ссылки const для примитивов является ошибкой. Либо вам нужно изменить значение, и в этом случае вы передаете неконстантную ссылку, либо вам просто нужно получить доступ к значению, и в этом случае вы передадите константу.

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

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

Ответ 3

Основное различие между возвратом значения и возвратом ссылки const - это то, что вы можете const_cast ссылаться и изменять значение.

Это пример плохого дизайна и попытка создать интеллектуальный дизайн, где более простого и сжатого дизайна было бы более чем достаточно. Вместо того, чтобы просто возвращать ценность, автор заставляет читателей кода думать, какое намерение он мог бы иметь.

Ответ 4

Нет большой пользы. Я видел это в рамочных или макрогенерированных геттерах и сеттерах раньше. Макрокод не различал примитивные и не-POD-типы и просто использовал const type& по всей доске для сеттеров. Я сомневаюсь, что это проблема эффективности или подлинное недоразумение; Скорее всего, это проблема согласованности.

Ответ 5

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

Ответ 6

Нет смысла и выгоды, кроме

void MyClass::setFoo(const int foo)
void MyClass::setFoo(const int& foo)

так как тогда вы не сможете повторно использовать переменную "foo" внутри реализации "setFoo". И я считаю, что "int &" просто потому, что Гай просто привыкает передавать все вещи по ссылке const, и в этом нет ничего плохого.