Почему я могу присвоить новое значение ссылке, и как я могу сделать ссылку на что-то еще?
У меня есть пара вопросов, связанных с использованием ссылок в С++.
-
В приведенном ниже коде, как он работает и не дает ошибку на строке q = "world";
?
#include <iostream>
using namespace std;
int main()
{
char *p = "Hello";
char* &q = p;
cout <<p <<' '<<q <<"\n";
q = "World"; //Why is there no error on this line
cout <<p <<' '<<q <<"\n";
}
-
Как ссылка q может быть повторно инициализирована на что-то еще?
-
Не является ли строковым литералом, p = "Hello"
, константой или в пространстве только для чтения? Итак, если мы это сделаем,
q = "World";
не будет ли изменена строка в p
, которая должна быть постоянной?
-
Я читал о переменных ссылочного типа С++, поскольку их нельзя повторно инициализировать или переназначить, поскольку они хранятся "внутренне" в качестве постоянных указателей. Таким образом, компилятор выдаст ошибку.
Но как можно переназначить ссылочную переменную?
int i;
int &j = i;
int k;
j = k; //This should be fine, but how we reassign to something else to make compiler flag an error?
Я пытаюсь понять эту ссылку и, возможно, пропустил некоторые ключевые вещи, связанные с этими вопросами.
Так что любые указатели, чтобы очистить это, были бы полезны.
Ответы
Ответ 1
-
- a) Он не может, строка, которую вы цитируете, не меняет ссылку
q
, она меняет p
.
- b) Литерал не является постоянным, но
p
является указателем, который указывает на литерал.
Указатель можно изменить, на что указывает, не может.
q = "world";
указывает на указатель p
на что-то еще.
-
Вам кажется, что этот код
int i;
int &j = i;
int k;
j = k;
переназначает ссылку, но это не так.
Он присваивает значение k
i
, j
по-прежнему относится к i
.
Я бы предположил, что это ваше главное недоразумение.
Ответ 2
Важная информация о ссылках, которые, как я думаю, вам не хватает, заключается в том, что, как только ссылка привязана к объекту, вы никогда не сможете переназначить ее. С этого момента в любой момент, когда вы используете ссылку, она неотличима от использования объекта, к которому он относится. Например, в вашем первом фрагменте кода, когда вы пишете
q = "World";
Так как q
является ссылкой, привязанной к p
, это эквивалентно написанию
p = "World";
Что именно меняется, когда указывает p
, а не содержимое строки, на которую она указывает. (Это также объясняет, почему он не падает!)
Что касается вашего второго вопроса, ссылки не могут быть переназначены после привязки к объекту. Если вам нужна ссылка, которая может изменить референт, вместо этого вы должны использовать указатель.
Надеюсь, это поможет!
Ответ 3
a) Как ссылка q может быть повторно инициализирована на что-то еще?
Это не может быть!
Контрольная переменная остается псевдонимом, к которому она была инициализирована во время создания.
b) Не является строковым литералом, p = "Hello", константой/только для чтения. Итак, если мы это сделаем,
Нет, это не так.
char* &q = p;
Здесь q
- ссылка на указатель типа char p
. Строка здесь постоянна, поэтому указатель не указан, ее можно указать на другую строку, а ссылка является псевдонимом этого указателя, а не строковым литералом, поэтому он действителен.
c) Второй вопрос, который у меня есть, я прочитал о переменных ссылочного типа С++, поскольку их нельзя повторно инициализировать/переназначить, поскольку они хранятся "внутренне" в качестве постоянных указателей. Поэтому компилятор даст ошибку.
int i;
int &j = i;
int k;
j = k; //This should be fine, but how we reassign to something else to make compiler flag an error
Не переназначает ссылку. он изменяет значение переменной, к которой он был псевдоним.
В этом случае он изменяет значение i
на k
Ответ 4
Относитесь к ссылке как псевдоним, и я надеюсь, что мир ссылок будет намного легче понять.
int p; // Declares p as an integer; Defines p & allocates space
int &q = p ; // Declares a Reference. Though they are symbolically 2 variables,
// they essentially refer to same name and same memory location.
Итак, p = 5 и q = 5 будут одинаковыми.
В вашем примере
char *p = "Hello"; // Declares your pointer to "Hello". p has its own existence.
char* &q = p; // This now creates a reference (alias) to p with name q.
Таким образом, все p, q являются именами объекта/объекта (памяти).
Итак, если вы назначаете q что-то, оно также отражается в p. Coz это то же самое, что и присвоение p.
Итак, q = "Мир" , означает, что p тоже теперь указывает на "Мир" . то есть место Памяти, на которое ссылаются р и q, - содержит адрес первого символа "Мир" .
Надеюсь, что на второй вопрос не нужно ответить, если вы понимаете понятие ссылки как псевдоним.