Ответ
Нет, это фундаментальное свойство ссылки в 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; // Адреса совпадают
Альтернативы, если нужно "перенаправление":
- *Указатель (`T`):** Может быть изменён.
int* ptr = &a; ptr = &b; // Теперь ptr указывает на b 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- Переменная-член ссылочного типа в классе может быть инициализирована только в списке инициализации конструктора и также не может быть изменена.
Вывод: Ссылка — это инструмент для работы с существующим объектом под другим именем, а не для динамического изменения цели. Для последнего используйте указатели.
Ответ 18+ 🔞
А, ну это классика, ёпта! Ссылка в C++ — это как татуха на жопе, один раз набил и всё, хуй с горы, переделать не получится. Она с момента рождения приклеивается к своему объекту намертво, и никакого "а давайте я теперь буду на другую переменную ссылаться" не предусмотрено. Это псевдоним, альтернативное имя, а не какая-то хитрая жопа с дистанционным управлением.
Смотри, вот пример, где все пытаются её "переназначить" и нихуя не выходит:
int a = 10;
int b = 20;
int& ref = a; // ref — это теперь просто второе имя для 'a'. Всё.
std::cout << ref << std::endl; // Выведет: 10
// А вот тут начинается магия иллюзий. Думаешь, ref теперь на 'b' ссылается?
ref = b; // А вот хуй там! Это не переназначение ссылки!
// Это обычное присваивание. Берёшь значение из 'b' (20) и кладёшь его туда, на что ref ссылается, то есть в 'a'.
std::cout << a << std::endl; // Выведет: 20 (ой, бля! 'a' поменялась! Вот же манда с ушами!)
std::cout << ref << std::endl; // Выведет: 20 (потому что ref всё ещё привязан к 'a', которая теперь 20)
std::cout << &ref << " == " << &a << std::endl; // Адреса одинаковые, доверия ебать ноль к другим вариантам.
Так что делать, если тебе реально нужно эту привязку менять?
- *Указатель (`T`):** Старый добрый костыль. Его можно вертеть как хочешь.
int* ptr = &a; ptr = &b; // А вот теперь ptr реально показывает пальцем на b. Лепота. 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. a осталась в покое.- Ссылка-член класса: Её тоже только один раз в списке инициализации конструктора прикрутить можно, и потом — терпения ноль ебать, сиди и не рыпайся.
Короче, вывод простой: Если тебе нужно имя для объекта, которое не будет прыгать — бери ссылку. Если тебе нужна штука, которую можно перенацеливать — бери указатель или reference_wrapper. Ссылка на то и ссылка, чтобы быть верной одной переменной до конца своих дней, как пёс, блядь.