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
}

Это особый случай.

Другие вопросы по тегам