MrNexeon
@MrNexeon

Когда допустимо возвращение ссылки в функции? Когда ссылки на константу?

Всем добрый день, я начинающий в C++.

Немного запутался с понятием ссылочного возвращаемого значения в функции, а так же возвращаемым значением в виде ссылки на константу. (int &func() и const int &func())

Кто может понятно объяснить чем они отличаются и в каких целях используются?
Желательно с примерами, буду очень благодарен.

P.S. В гуголе не смог найти полный ответ на вопрос.
  • Вопрос задан
  • 767 просмотров
Решения вопроса 2
Отличаются тем, что во втором случае объект по ссылке изменять нельзя. От возврата по значению отличаются тем, что при возврате по значению происходит копирование объекта со всеми вытекающими:
1. Это может быть накладно
2. Результат - это копия, поэтому изменения, внесённый в неё - это изменения в копии, а не в том объекте, который возвращался. По этой причине, например, operator [] у класса-массива должен возвращать ссылку, чтобы изменяя полученную ссылку, изменялось бы значение, которое лежит в массиве.

Ссылка в этом смысле не отличается от указателя, кроме того, что не может быть null. Поэтому нельзя, например, возвращать ссылку на какую-то временную переменную:
int & foo()
{
  int x = 100;
  return x;
}
int main()
{
  int & y = foo();
  y = 10; // UB
}

Переменная x тут умрёт по выходе из foo, и y будет ссылаться на уже мёртвую переменную. Но можно возвращать ссылку на член класса, если объект класса будет жить дольше, чем ссылка. Т.е. так можно:
class Test
{
  int x;
public:
  int & getx() { return x; }
};
int main()
{
  Test t;
  int & y = t.getx();
  y = 10; // t.x будет равен 10
}

А вот так опять нет:
class Test
{
  int x;
public:
  int & getx() { return x; }
};
int main()
{
  int * y;
  {
    Test t;
    y = &t.getx();
  }
  *y = 10; // UB, t умирает в конце блока, x тоже, а обращение идёт уже после
}
Ответ написан
Olej
@Olej
инженер, программист, преподаватель
Когда допустимо возвращение ссылки в функции?

Если я правильно понял ваш вопрос (1-й из 2-х ;-)):
1. возврат ссылки имеет смысл тогда, когда не хочется копировать большой возвращаемый объект через стек
2. поэтому довольно странный ваш пример int& func() - int ничуть не короче адреса, поэтому ссылка здесь не имеет никакого смысла
3. при возврате ссылки нужно следить (очень частая и тяжёлая ошибка), чтобы объект, на который возвращается ссылка, не был локальным в функции, и существовал к моменту возврата (это не проблема в языках с подсчётом ссылок, например, Go, но в C++ это проблема):
int& func() {
   int x = ...
   return x;
}

int& func( int x ) {
   x = ...
   return x;
}

- это будет тяжёлая ошибка.

А вот так будет нормально:
int x;
int& func() {
   x = ...
   return x;
}

int& func() {
   static int x;
   x = ...
   return x;
}

int& func( int& x ) {
   x = ...
   return x;
}

Естественно, int в этих примерах - бессмысленно ... но подставьте вместо него объект любого класса.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
P.S. В гуголе не смог найти полный ответ на вопрос.

Плохо искали, вот первые три ссылки (там объяснено всё и очень-очень подробно):

https://stackoverflow.com/questions/795674/which-a...

https://isocpp.org/wiki/faq/const-correctness

www.bogotobogo.com/cplusplus/object_returning.php

Там и примеры с операторами есть и пр.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы