Skip to content

CPP 02. Ссылки. lvalue и rvalue ссылки. Передача параметров в функции по ссылке. Автоматическое выведение типа.

Dmitriy Pisarenko edited this page Sep 7, 2023 · 3 revisions

Ссылки

Ссылка (alias) – механизм передачи параметров в функцию и возврата из функции. По сути это ещё одно имя того же самого данного.

Ссылка - не тип данных!

Ссылка всегда инициализирована (не может указывать на null)

Пример:

int i;
int& ai = i;
ai = 5; //то же самое, что и i = 5;

Но такое использование ссылок - абсурд. Ссылки надо использовать для того, чтобы избавиться от указателей.

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

Lvalue и rvalue ссылки

Lvalue ссылки - это ссылки на существующие объекты, которые имеют имена. Они объявляются с помощью оператора "&". Пример объявления lvalue ссылки:

int a = 10;
int& b = a; // объявление lvalue ссылки на переменную a

Rvalue ссылки - это ссылки на временные объекты, которые не имеют имена. Они объявляются с помощью оператора "&&". Пример объявления rvalue ссылки:

int&& c = 20; // объявление rvalue ссылки на временный объект

Примеры из лекций:

#include <iostream>

void f(int) {}

int main()
{
    int i = 0;

    int& lref1 = i;
    int& lref2(i);
    int& lref3{ i };
    int& lref4 = { i };

    int& lv1 = i;// Ok!
    int& lv2 = 2;// Error!(не lvalue)
    int& lv3 = i + 1;// Error!(не lvalue)
    const int& lv4 = i + 1;// Ok!(создается объект)
    ++lv1;// Ok!

    int&& rv1 = i;// Error!(не rvalue)
    int&& rv2 = 2;// Ok!
    int&& rv3 = i + 1;// Ok!
    const int&& rv4 = i + 1;// Ok!
    ++rv2;// Ok!

    int&& rv5 = rv2;// Error!(не rvalue)
    int& lv5 = rv2;// Ok!

    int&& rv6 = (int)i;// Ok!( int(i) )
    int&& rv7 = std::move(i);// Ok!

    void(&reff)(int) = f;
    reff(1);
}

Передача параметров в функции по ссылке

Передача параметров в функции по ссылке позволяет изменять значения объектов внутри функции, не создавая копий объектов. Для передачи параметров по ссылке используются lvalue ссылки.
Пример:

void swap(int& x, int& y) {
    int temp = x;
    x = y;
    y = temp;
}

int a = 10, b = 20;
swap(a, b);

Автоматическое выведение типа

Автоматическое выведение типа - это возможность компилятора определить тип переменной на основе значения, которое ей присваивается. Для автоматического выведения типа используется ключевое слово "auto".

Примеры из лекций:

# include <iostream>

int main()
{
    int i = 0;
    const int ci = 0;
    int& lv = i;
    const int& clv = ci;
    int&& rv = i + 1;

    // тип int
    {
    auto x1 = i;
    auto x2 = ci;
    auto x3 = lv;
    auto x4 = clv;
    auto x5 = rv;
    auto x6 = i + 1;
    }

    // тип int&
    {
    auto& refx1 = i;
    auto& refx3 = lv;
    auto& refx5 = rv;
    }

    // тип const int&
    {
    auto& crefx2 = ci;
    auto& crefx4 = clv;
    }

    // тип const int&
    {
    const auto& crefx1 = i;
    const auto& crefx2 = ci;
    const auto& crefx3 = lv;
    const auto& crefx4 = clv;
    const auto& crefx5 = rv;
    const auto& crefx6 = i + 1;
    }

    // тип int&
    {
    auto&& refx1 = i;
    auto&& refx3 = lv;
    auto&& refx5 = rv;
    }

    // тип const int&
    {
    auto&& crefx2 = ci;
    auto&& crefx4 = clv;
    }

    // тип int&&
    {
    auto&& refx6 = i + 1;
    }
}
Clone this wiki locally