Pointeurs et références en C + + Partie 2
En continuant avec cette tentative de série de posts sur les pointeurs et les références, qui ont commencé à parler des pointeurs , les références de discuter aujourd'hui.
Une référence est un alias pour un objet, d'un pseudonyme. Et qui dit cela n'est pas moi, mais la très Stroustrup Bjarne , autour du thème de votre 5,5 livre , dont le contenu est tellement bon que je ne constatons aujourd'hui que le couvercle a une vague déferlante en forme de C. J'aime que la couverture!
Références Déclarant
Une référence à un type particulier est déclaré en ajoutant le caractère & (esperluette ou perluète ) après le nom du type de référence. Notez que la même manière que dans la déclaration de pointeurs, nous traitons avec le caractère & comme une note, et non un opérateur. Aucun opérateur d'une déclaration des pointeurs ou des références. C'est juste un langage de notation. Étant donné un type T, l'expression signifie référence T & T. Par exemple:
i ; // Declaram referências para a variável i. // Todas as formas são equivalentes, mas preferimos a primeira. // Note que os tipos das referências tem que ser os mesmos // que os das variáveis referenciadas. int & ra = i ; int & rb = i ; int & rc = i ; // Diferentemente de ponteiros, a linha abaixo gera um // erro de compilação. .. / / Déclare une variable entière d'origine / / Il pourrait également être char, float, etc int i;. / / Déclare les références à la variable i. / / Toutes les formes sont équivalentes, mais je préfère le premier / / Notez que les types références doivent être les mêmes / / les variables référencées int & ra = i;. & rb = int i; int & rc = i / / Contrairement aux pointeurs, la ligne ci-dessous génère une erreur / / compilation. & r1, & r2 ; Savez-vous pourquoi Int & R1, R2 &?;
Bien que dans C + + références pointeurs souviens un peu, ils sont assez différents. Contrairement à ce qui se passe avec des pointeurs, une référence doit être initialisé lors de sa déclaration. Essayer de déclarer une référence sans l'initialiser génère une erreur au moment de la compilation, c'est à dire, le compilateur va cracher au visage "Lost Playboy perdu." La seule exception à cette règle est pour référence déclarée comme externe , car ils seront initialisés à un autre moment dans le programme, mais c'est une autre diatribe.
Si vous essayez de tricher en déclarant une référence externe sans initialisation du compilateur ne se plaindra pas. Si elle n'a jamais été utilisé, ok. Si le compilateur est intelligent et note qu'il n'est pas utilisé, il peut même le retirer de la liste des symboles. Mais si elle est utilisée n'importe où dans le programme, l'éditeur de liens vous rire au nez de rire "undefined reference to 'nome_da_variavel." Alors faire les choses correctement. Déclaré une référence? Donc, il iniclalize. extern? Etes-vous sûr que vous savez ce que vous faites?
La logique derrière cela est que la référence est destiné à être un nom pour quelque chose. Si vous n'avez pas de boot, il ne sera pas le nom pour rien, alors il ne fait aucun sens. Un détail très important est que le démarrage d'une référence n'est pas à attribuer une valeur à elle. Comme prório Bjarne dit, aucun opérateur opère sur des références, c'est à dire, il n'ya aucun moyen d'assigner, additionner, soustraire, etc, avec une référence. Comme une référence est un alias pour un objet, chaque opérateur agit objet NESE, pas dans la référence. Une fois initialisé, une référence toujours référence au même objet.
Le premier piège avec des références, ainsi que des pointeurs sur la question de la taille. Alors que la taille d'un pointeur (et d'autres structures de données) peuvent être obtenus auprès de l'opérateur sizeof, la taille d'une référence ne peut être obtenue par des techniques classiques, comme lors de l'application de l'opérateur sizeof sur une référence, nous sommes effectivement d'appliquer l'opérateur sur l'objet auquel il se réfère, comme nous l'avons vu dans le paragraphe précédent.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | char c; int i; Double D; rc = c ; char & rc = c; ri = i ; int & ri = i; rd = d ; Double & rd = D; / / L'opérateur sizeof dit la taille du type de son argument. "Size of char: " << sizeof ( c ) << " bytes" << endl ; cout <<"Taille des caractères:" <<sizeof (c) <<"octets" <<endl; "Size of int: " << sizeof ( i ) << " bytes" << endl ; cout <<"Taille de int:" <<sizeof (i) <<"octets" <<endl; "Size of double: " << sizeof ( d ) << " bytes" << endl ; cout <<"Taille du double:" <<sizeof (d) <<"octets" <<endl; endl ; cout <<endl; "Size of char&: " << sizeof ( rc ) << " bytes" << endl ; cout <<"Taille des caractères &:" <<sizeof (rc) <<"octets" <<endl; "Size of int&: " << sizeof ( ri ) << " bytes" << endl ; cout <<"Taille de l'int &:" <<sizeof (ri) <<"octets" <<endl; "Size of double&: " << sizeof ( rd ) << " bytes" << endl ; cout <<"Taille de la double &:" <<sizeof (e) <<"octets" <<endl; |
Les techniques de la taille des références sont au-delà de la portée de ce texte, mais j'ai l'intention d'en parler plus tard. Pour l'instant, je vais juste dire non à démontrer que, le cas échéant, de la taille d'une référence est identique à la taille d'un pointeur.
La bonne partie de l'histoire est souvent la taille des pointeurs et les références sont beaucoup moins pertinents que les tailles des objets liés ou référencés. Personnellement, je n'ai jamais eu besoin d'utiliser cette information, mais pour le développement ou sur des architectures différentes pour les systèmes embarqués, il est devenu plus intéressant.
Utilisation des références
L'utilisation de références est déjà beaucoup plus simple que celle des pointeurs qui ne sont pas nécessaires aux opérateurs d'extraire les adresses ou dé-référencement. Référence des variables sont utilisées comme des variables ordinaires, constatant que l'opération effectuée dans une référence affecte toujours l'objet référencé.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | int x, y; rx = x ; int & x = rx; ry = y ; int & y = ry; ; x = 13; ; y = 10; ; // A atribuição é automaticamente aplicada em x. Rx = 42 / / L'affectation est automatiquement appliquée à x. // O incremento é automaticamente aplicado em y. ry + + / / L'incrément est automatiquement appliquée à y. "x: " << x << endl ; // Valor de x. cout <<"x:" <<x <<endl / / valeur de x. "y: " << y << endl ; // Valor de y. cout <<"y:" <<y <<endl / / valeur de y. "rx: " << rx << endl ; // Valor de rx == x. cout <<"rx:" <<rx <<endl / / valeur == x. rx "ry: " << ry << endl ; // Valor de ry == y. cout <<"ry:" <<ry <<endl / / valeur == ry y. |
L'utilisation d'une telle référence est transparente pour le programmeur, il n'a pas besoin de savoir qui est une référence. Il suffit d'utiliser comme une variable ordinaire. Avec mon imagination limitée ne vois pas comment quiconque pourrait être excommunié pour l'utilisation de références inappropriées. Bien que toujours un peu l'esprit de porc qui peut faire chier avec des références, est beaucoup plus facile d'obtenir déclenché par Saci lors de la manipulation de pointeurs.
Adresses et Références
Du point de vue de Murphy , les références sont laids, ennuyeuse et stupide, car il ya peu de potentiellement dangereux à faire avec eux. Même si il ya beaucoup d'adresse surprises (le fera?). Considérons le code ci-dessous:
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 10 ; int a = 10; 13 ; int b = 13; ra = a ; int & ra = a; rb = b ; int & b = rb; ; Ra = 42; ; RB = 7; "ra = " << ra << endl ; // O valor de ra == 42. cout <<"ra =" <<Ra <<endl / / La valeur de ra == 42. "rb = " << rb << endl ; // O valor de rb == 7. cout <<"rb =" <<rb <<endl / / La valeur de RB == 7. "a = " << a << endl ; // O valor de a == ra == 42. cout <<"a =" <<a <<endl / / La valeur de ra == a == 42. "b = " << b << endl ; // O valor de b == rb == 7. cout <<"b =" <<b <<endl / / La valeur de RB == b == 7. "&a = " << & a << endl ; // O endereço de a. cout <<"& a =" <<& une <<endl / / L'adresse de a. "&b = " << & b << endl ; // O endereço de b. cout <<"& b =" <<& b <<endl / / L'adresse de b. "&ra = " << & ra << endl ; // O endereço de ra == &a. cout <<"& ra =" <<& ra <<endl / / L'adresse de ra == & a. "&rb = " << & rb << endl ; // O endereço de rb == &b. cout <<"& rb =" <<& rb <<endl / / L'adresse == rb & b. |
Dans les lignes 17 et 18, je déclare deux variables entières (aurait pu faire cela avec un exemple ...). Dans les lignes 20:21 Je déclare deux références, le référencement des deux variables précédentes. Ensuite, les variables de Ra et Rb sont simplement des alias pour les variables a et b. Comme nous l'avons vu précédemment, tout opérateur appliqué à des références agit effectivement sur les objets référencés, de sorte que chaque paire variable de référence a toujours la même valeur.
La partie intéressante à noter est que les adresses des références sont exactement la même adresse, ils référence à des variables au lieu de pointeurs qui avaient leur propres adresses. Pourquoi? Parce que vous êtes tombé dans Gotcha Trickster . Rappelez-vous que choses sur aucun opérateur n'est applicable à une référence? Eh bien, l'opérateur & utilisé ici est le «adresse», qui est aussi appliqué directement aux variables d'origine et non pas dans les références. Les mêmes techniques utilisées pour obtenir le ninja de tailles des références sont nécessaires pour obtenir les adresses d'entre eux.
Là encore, la partie la plus amusante est que le mécanisme de référence est conçu pour être aussi transparents que possible pour le programmeur. Tailles et l'adresse physique de références sont des informations non pertinentes du point de vue de la programmation «normale» en C + +.
Différences et similitudes entre les pointeurs et les références
Les deux références sont des pointeurs en tant que mécanismes d'indirection en C + +, ou des mécanismes sont utilisés pour cela d'un symbole (variable) Je suis capable de manipuler d'autres objets.
Les principales utilisations pour les pointeurs sont généralement liés à la gestion et la manipulation de la mémoire dynamique, création et destruction d'objets de différentes formes et des moments spéciaux, ainsi que "passer par référence» (il cite). Depuis les références sont utilisées principalement sur le passage par référence (je me demande pourquoi?) Et la surcharge des opérateurs.
Fondamentalement, tout ce que nous pouvons faire avec des références peut être émulé avec des pointeurs. Déjà recíprocra n'est pas toujours vrai. Le grand avantage d'entre eux cependant, est que l'indirection devenir complètement transparent pour le programmeur.
Une allégorie intéressante pour aider à mieux comprendre les différences entre les pointeurs et les références est le surnom. Par exemple: Imaginez qu'une personne, par exemple, Carlos Caetano Bledorn Verri ., notre variable est l'objet original Dunga est déjà une référence à Carlos Caetano Bledorn Verri, il est un alias pour le même objet sont la même personne. Déjà mère de Dunga (Carlos Caetano Bledorn Verri ou, peu importe), qui est citée par les fans main ferme, peut être considéré comme un pointeur vers elle, pour certains opérateurs de données de vocabulaire, fait un compliment, est en fait indirectement ciblés à elle.
Liens
- referencias.zip (toutes les sources de la poste);
- 01-declaracao.cpp
- 02-tamanhos.cpp
- 03-utilizando.cpp
- 04-enderecos.cpp
- Le coupable
Commentaires
- http://caloni.com.br Wanderley Caloni
- http://caloni.com.br Wanderley Caloni
- http://blabos.org bavarder
- http://blabos.org bavarder
- http://caloni.com.br Wanderley Caloni
- http://caloni.com.br Wanderley Caloni
- http://www.jorgepereira.com.br Jorge Pereira
- http://www.jorgepereira.com.br Jorge Pereira
- http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional Caloni.com.br »Blog Archive dernières recherches» dans la blogosphère nationale
- http://www.brunodanielmarinho.com Bruno
- http://www.brunodanielmarinho.com Bruno
- http://blabos.pip.verisignlabs.com/ bavarder
- http://blabos.pip.verisignlabs.com/ bavarder
- Cairo Rocha
- Blaber http://blabos.org des bleb

