web-dev-qa-db-fra.com

Pourquoi puis-je attribuer une nouvelle valeur à une référence et comment puis-je faire référence à quelque chose d'autre?

J'ai quelques questions liées à l'utilisation des références en C++.

  1. Dans le code ci-dessous, comment cela fonctionne-t-il et ne donne-t-il pas d'erreur à la ligne 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";
    }
    
    1. Comment réinitialiser une référence q à autre chose?

    2. N'est-ce pas la chaîne littérale, p = "Hello", un espace constant ou en lecture seule? Donc, si nous le faisons,

      q = "World";
      

      la chaîne de p qui est supposée constante ne serait-elle pas modifiée?

  2. J'ai lu sur les variables de type de référence C++ car elles ne peuvent pas être réinitialisées ou réaffectées, car elles sont stockées "en interne" en tant que pointeurs constants. Un compilateur donnerait donc une erreur.

    Mais comment réellement une variable de référence peut-elle être réaffectée?

    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?
    

    J'essaie de saisir cette référence, et en cela peut-être manqué certains éléments clés liés, donc ces questions.

Donc, tous les conseils pour éclaircir ce point seraient utiles.

29
goldenmean
    • a) Non, la ligne que vous citez ne change pas la référence q, elle change p.
    • b) Non, le littéral est constant, mais p est un pointeur qui pointe vers un littéral. Le pointeur peut être changé, ce qui est pointé ne le peut pas. q = "world"; fait pointer le pointeur p vers autre chose.
  1. Vous semblez penser que ce code

    int i;
    int &j = i;
    int k;
    j = k;
    

    réaffecte une référence, mais ce n'est pas le cas. Cela affecte la valeur de k à i, j fait toujours référence à i. Je suppose que c'est votre principal malentendu.

58
john

Un détail important sur les références qui, je pense, vous manque, est qu'une fois la référence liée à un objet, vous ne pouvez jamais le réaffecter. À partir de ce moment, chaque fois que vous utilisez la référence, il est impossible de la distinguer de l'utilisation de l'objet auquel elle se réfère. Par exemple, dans votre premier morceau de code, lorsque vous écrivez

q = "World";

Puisque q est une référence liée à p, cela équivaut à écrire

p = "World";

Ce qui change simplement où p pointe, pas le contenu de la chaîne vers laquelle il pointe. (Cela explique également pourquoi il ne plante pas!)

Quant à votre deuxième question, les références ne peuvent pas être réaffectées une fois liées à un objet. Si vous avez besoin d'une référence qui peut changer son référent, vous devez plutôt utiliser un pointeur.

J'espère que cela t'aides!

23
templatetypedef

a) Comment réinitialiser une référence q à autre chose?

Ça ne peut pas être!

Une variable de référence reste un alias auquel elle a été initialisée au moment de sa création.


b) N'est-ce pas la chaîne littérale, p = "Bonjour", un espace constant/en lecture seule. Donc, si nous le faisons,
Non, ce n'est pas le cas.

char* &q = p;

Ici q est une référence à un pointeur de type char p. La chaîne ici est constante, le pointeur ne l'est pas, il peut être pointé vers une autre chaîne, et la référence est un alias à ce pointeur et non le littéral de la chaîne, il est donc valide.


c) La deuxième question que j'ai est que j'ai lu sur les variables de type référence C++ car elles ne peuvent pas être réinitialisées/réaffectées, car elles sont stockées "en interne" en tant que pointeurs constants. Un compilateur donnerait donc une erreur.

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

Ne réattribue pas la référence. il modifie la valeur de la variable à laquelle il était alias.

Dans ce cas, il change la valeur de i en k

3
Alok Save

Traitez la référence comme un nom d'alias et j'espère que le monde de la référence sera beaucoup plus facile à comprendre.

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.

Donc, p = 5 et q = 5 seront tous les mêmes.

Dans votre exemple,

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.

Donc, dans l'ensemble, p q sont les noms de l'entité/objet (mémoire).

Donc, si vous attribuez quelque chose à q, cela se reflète également dans p. Coz c'est la même chose que l'affectation à p. Donc q = "Monde", signifie que p pointe aussi vers "Monde". c'est-à-dire l'emplacement mémoire auquel p q se réfèrent tous les deux - contient l'adresse du premier caractère de "World".

J'espère que la deuxième question n'a pas besoin d'être répondue si vous comprenez la notion de référence comme un alias.

3
jmishra