Можно ли переназначить ссылку в C++ на другой объект (изменить адрес памяти, на который она ссылается)?

«Можно ли переназначить ссылку в C++ на другой объект (изменить адрес памяти, на который она ссылается)?» — вопрос из категории C++ Core, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, это фундаментальное свойство ссылки в C++. Ссылка должна быть инициализирована при объявлении и не может быть изменена для ссылки на другой объект в течение всей своей жизни. Она является псевдонимом (альтернативным именем) для уже существующего объекта.

Пример, демонстрирующий невозможность переназначения:

int a = 10;
int b = 20;

int& ref = a; // ref — это псевдоним для переменной 'a'
std::cout << ref << std::endl; // Выведет: 10

// Попытка "переназначить" ссылку на 'b'
ref = b; // Это НЕ переназначает ссылку!
// На самом деле это присваивание значения 'b' объекту, на который ссылается ref (т.е. переменной 'a').

std::cout << a << std::endl;  // Выведет: 20 (значение 'a' изменилось!)
std::cout << ref << std::endl; // Выведет: 20 (ref по-прежнему ссылается на 'a')
std::cout << &ref << " == " << &a << std::endl; // Адреса совпадают

Альтернативы, если нужно "перенаправление":

  1. *Указатель (`T`):** Может быть изменён.
    int* ptr = &a;
    ptr = &b; // Теперь ptr указывает на b
  2. std::reference_wrapper (из <functional>): Обёртка, которую можно переназначить.
    #include <functional>
    std::reference_wrapper<int> ref_wrap = a;
    ref_wrap = b; // Теперь ref_wrap ссылается на b
    ref_wrap.get() = 30; // Меняет значение b на 30
  3. Переменная-член ссылочного типа в классе может быть инициализирована только в списке инициализации конструктора и также не может быть изменена.

Вывод: Ссылка — это инструмент для работы с существующим объектом под другим именем, а не для динамического изменения цели. Для последнего используйте указатели.