C++ возврат по ссылке, каковы эффекты?
Возьмите следующий код, где функция возвращается по ссылке:
#include <cstdio>
using namespace std;
int & myFunction(int & input) {
return input;
}
int main() {
int x;
int y = 10;
x = myFunction(y);
printf("x is %d\n",x); // x is 10
printf("y is %d\n",y); // y is 10
x = 20;
printf("x is %d\n",x); // x is 20
printf("y is %d\n",y); // y is 10
return 0;
}
Кроме очевидной ловушки возврата ссылки на локальную переменную функции (что здесь не так), есть ли что-то, на что следует обратить внимание при такой настройке? Другими словами, есть ли что-нибудь "больше" в этом коде, чем функция, которая просто возвращает вещи по ссылке, чтобы избежать ненужных операций копирования?
2 ответа
Кроме очевидной ловушки возврата ссылки на локальную переменную функции (что здесь не так), есть ли что-то, на что следует обратить внимание при такой настройке?
Нет, не совсем, это совершенно правильно, но и не имеет никаких преимуществ. (в текущем состоянии myFunction
)
во избежание ненужных операций копирования?
Здесь все еще делается копия:
int x;
int y = 10;
x = myFunction(y); // value of y is copied to x.
Это менее читабельно и ничего не ускоряет, когда дело доходит до обычной инициализации:
int x;
int y = 10;
x = y;
В такой ситуации нет причин делать это, просто придерживайтесь обычной инициализации.
Конечно, если myFunction
добавляет некоторую модификацию к более сложному объекту, чем int&
тогда вы можете воспользоваться возвратом ссылки, как тогда:
chain.method().calls();
Код, который вы предоставили, работает, потому что вы передаете переменную своей функции по ссылке, и все равно возвращаете ее по ссылке. Это соответствует и работает, но странно. Зачем вам возвращать ту же переменную, которую вы передаете по ссылке? (Я только что вспомнил из комментариев, что это полезно, например, для создания цепочки в std::ostream.)
С другой стороны, если вы передадите эту переменную по значению, у вас будет свисающая ссылка, и она не будет работать. Так что это не сработает:
int & myFunction(int input) {
return input;
}
По моему мнению, единственное возвращение по ссылке, которое я считаю подходящим, - это если вы возвращаете переменную из метода класса. Кроме того, я не думаю, что вы должны возвращаться по ссылке вообще.
Вы можете перехватить переменную как постоянную ссылку и избежать ее копирования, если хотите, без висячего, если вы сделаете это:
int myFunction(int input) {
return input;
}
int main()
{
const int& myInt = myFunction();
//myInt is still valid here
}
Это особый случай.