С++ ссылка на временный объект

156
11 сентября 2019, 19:40

Хочу разобраться в двух следующих вопросах:

1) До какого момента ссылка на временный объект остается валидна? Иначе говоря, когда временный объект уничтожается?

void func_1(const object &_obj)
{
    // Долгая и сложная работа с _obj.
}
int main()
{
    func_1(object(...));
}

2) Видел код, подобный этому:

object a, b;
// ...
object &temp = a;
a = b;
b = temp;
// Код работал, обменивая значения местами, хотя я всегда думал, 
// что ссылка - это просто синоним, и данный код должен был привести
// к тому, что в `a` и `b` окажется изначальное значение `b`.
Answer 1

1) До какого момента ссылка на временный объект остается валидна? Иначе говоря, когда временный объект уничтожается?

void func_1(const object &_obj)
{
    // Долгая и сложная работа с _obj.
}
int main()
{
    func_1(object(...));
}

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

Не "настоящей" строки, а "логической" - которая заканчивается символом ;, а не символом переноса строки.

2) Видел код, подобный этому:

object a, b;
// ...
object &temp = a;
a = b;
b = temp;
// Код работал, обменивая значения местами, хотя я всегда думал, 
// что ссылка - это просто синоним, и данный код должен был привести
// к тому, что в `a` и `b` окажется изначальное значение `b`.

Это не может работать.

В оригинальном вопросе ситуация совсем другая. Там ссылку используют, чтобы поменять местами два указателя. Примерно так:

int *a = ...;
int *b = ...;
// ...
int &t = *b;
b = a;
a = &t;

По сути, это классический swap с использованием третьей переменной. Можно переписать его с использованием указателя вместо ссылки, смысл не изменится:

int *a = ...;
int *b = ...;
// ...
int *t = b;
b = a;
a = t;
Answer 2

Вот пример для наглядности. Запустите и посмотрите.

#include <iostream>


int main()
{
    int** arr = new int*[10];
    for (int i = 0; i < 10; i++){
        arr[i] = new int[10];
        for (int j = 0; j < 10; j++){
            arr[i][j] = i* 10 + j;
        }
    }
    for (int i = 0; i < 10; i++){
        for (int j = 0; j < 10; j++){
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << "-------------" << std::endl;
    int& ref = *arr[0];
    arr[0] = arr[1];
    arr[1] = &ref;
    for (int i = 0; i < 10; i++){
        for (int j = 0; j < 10; j++){
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }
    for (int i = 0; i < 10; i++){
        delete [] arr[i];
    }
    delete []arr;
    int a = 1, b = 2;
    int& temp = a;
    a = b;
    b = temp;
    std::cout << "------------" << std::endl;
    std::cout << "a:" << a << " b:" << b << std::endl;
}
READ ALSO
Откуда взялось значение

Откуда взялось значение

Имеется программа, которая берет из файла значения, записывает их в вектор типа структуры и затем по этим значениям рисует фигуру: поля структуры...

128
Отличия между enum в C и в C++

Отличия между enum в C и в C++

Правильно ли я понимаю, что C++, в отличии от C, запрещает неявное приведение между enum и int?

120
ffmpeg Как узнать PID для AVPacket?

ffmpeg Как узнать PID для AVPacket?

PID это идентификатор (13 бит) в MPEG-TS потоке (стриме), присваиваемый каждому элементарному транспортному пакету (ЭТП)

118
Не могу понять, где разница в двух кодах

Не могу понять, где разница в двух кодах

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

133