Перейти к содержимому
Теория · Функции · урок 4 из 13

Константная ссылка

В уроке о параметрах функция получала либо ксерокопию аргумента, либо сам оригинал. Копия int или double стоит дёшево, поэтому такие параметры передают по значению. Но объект может хранить тысячи значений, например длинный текст. Копировать такой объект при каждом вызове дорого: это как ксерокопировать целую книгу, чтобы коллега прочитал из неё одну страницу.

Отдать оригинал быстрее, но тогда функция сможет его испортить. Нужен третий способ: дать оригинал под стеклом музейной витрины. Читать можно, а исправить нельзя.

Ссылка только для чтения

Параметр, который функция только читает, объявляют константной ссылкой: const T&, где вместо T пишут тип параметра. Для int это const int&:

C++
#include <iostream>

void show(const int& x) {
    std::cout << x << '\n';
}

int main() {
    int n = 7;
    show(n);  // 7
    show(5);  // 5
}

Давайте разберём оба вызова:

  1. show(n): x становится другим именем n, копии нет, и функция печатает 7.
  2. show(5): обычная ссылка int& число не принимает, а константная принимает. Менять 5 функция всё равно не будет, поэтому компилятор разрешает такой вызов и печатает 5.

Если внутри show написать ++x, программа не скомпилируется. Компилятор ответит: cannot assign to variable 'x' with const-qualified type 'const int &'. Витрина работает: оригинал можно только читать.

Для int выгоды от константной ссылки нет, копия одного числа ничего не стоит. Её пишут для больших объектов, а int здесь только показывает правила.

Частая ошибка

Функция возвращает ссылку на свою локальную переменную:

C++
const int& sum(int a, int b) {
    int result = a + b;
    return result;  // ✗
}
TEXT
warning: reference to stack memory associated with local variable 'result' returned [-Wreturn-stack-address]

Компилятор только предупреждает, но result уничтожается при выходе из функции, и ссылка остаётся без переменной. Это как витрина, из которой унесли экспонат: стекло на месте, а под ним пусто.

Такую ссылку называют висячей, а чтение через неё — неопределённое поведение. Что тогда сделает программа, стандарт C++ не определяет, и ни на один результат полагаться нельзя.

Верните результат по значению: int sum(int a, int b). Тогда вызывающий код получит копию числа, и пропажа result ему не страшна.

Главное

  • Константная ссылка const T& передаёт объект без копии и запрещает функции его менять.
  • В параметр const int& можно передать и переменную, и число вроде 5.
  • Висячая ссылка указывает на уже уничтоженную переменную; чтение через неё — неопределённое поведение.
  • Не возвращайте ссылку на локальную переменную: верните результат по значению.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом