Подтвердить что ты не робот

Почему я могу присвоить новое значение ссылке, и как я могу сделать ссылку на что-то еще?

У меня есть пара вопросов, связанных с использованием ссылок в С++.

  • В приведенном ниже коде, как он работает и не дает ошибку на строке 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?
    

    Я пытаюсь понять эту ссылку и, возможно, пропустил некоторые ключевые вещи, связанные с этими вопросами.

Так что любые указатели, чтобы очистить это, были бы полезны.

4b9b3361

Ответ 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, - содержит адрес первого символа "Мир" .

Надеюсь, что на второй вопрос не нужно ответить, если вы понимаете понятие ссылки как псевдоним.