Pointers and references in C + + Part 2
Continuing with this attempt at series of posts about pointers and references, which began talking about pointers , references discuss today.
A reference is an alias for an object, an alias. Besides, who says this is not me, but the very Bjarne Stroustrup , around the topic of your 5.5 book , whose content is so good that I only notice today that the cover has a breaking wave in the form of C. I like that cover!
Declaring References
A reference to a particular type is declared by adding the character & (ampersand or ampersand ) after the name of the type of reference. Note that the same way as in the declaration of pointers, we are dealing with the & character as a rating and not an operator. There is an operator declaration of pointers or references. It is just a notational language. Given a type T, the expression means T & T Reference. For example:
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. / / Declare an integer variable original. / / It could also be char, float, etc.. Int i; / / Declare references to the variable i. / / All forms are equivalent, but prefer the first. / / Note that the types references must be the same / / the variables referenced. int & ra = i; int & rb = i; int & rc = i / / Unlike pointers, the line below generates a / / compilation error. & r1, & r2 ; You could tell why? Int & r1, & r2;
Although in C + + references remember a bit pointers, they are quite different. Unlike what happens with pointers, a reference must be initialized during its declaration. Trying to declare a reference without initializing it generates an error at compile time, ie, the compiler will spit in your face "Lost playboy lost." The only exception to this rule is for reference declared as extern , because they will be initialized at some other point in the program, but that's another conversation.
If you try to cheat by declaring an extern reference it without initializing the compiler will not complain. If it is never used, ok. If the compiler is smart and note that it is not used, it may even remove it from the list of symbols. But if it is used anywhere in the program, the linker will laugh in your face, laughing, "undefined reference to 'nome_da_variavel." So do things right. Declared a reference? Then iniclalize it. extern? Are you sure you know what you're doing?
The logic behind this is that a reference is intended to be a name for something. If you do not boot, it will not name for anything, so it makes no sense. A very important detail is to initialize a reference is not to assign a value to it. As prório Bjarne says, no operator operates on references, ie, there is no way to assign, add, subtract, etc. with a reference. As a reference is an alias for an object, each operator acts nese object, not in the reference. Once initialized, a reference will refer always to the same object.
The first trap with references, as well as pointers is the issue of size. While the size of a pointer (and other data structures) can be obtained with the sizeof operator, the size of a reference can not be obtained by conventional techniques, cited that in applying the sizeof operator in a referral, we are in reality applying the operator on the object to which it refers, as we saw in the previous paragraph.
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; / / The sizeof operator says the size of the type of its argument. "Size of char: " << sizeof ( c ) << " bytes" << endl ; cout << "Size of char:" << sizeof (c) << "bytes" << endl; "Size of int: " << sizeof ( i ) << " bytes" << endl ; cout << "Size of int:" << sizeof (i) << "bytes" << endl; "Size of double: " << sizeof ( d ) << " bytes" << endl ; cout << "Size of double:" << sizeof (d) << "bytes" << endl; endl ; cout << endl; "Size of char&: " << sizeof ( rc ) << " bytes" << endl ; cout << "Size of char &:" << sizeof (rc) << "bytes" << endl; "Size of int&: " << sizeof ( ri ) << " bytes" << endl ; cout << "Size of int &:" << sizeof (ri) << "bytes" << endl; "Size of double&: " << sizeof ( rd ) << " bytes" << endl ; cout << "Size of double &" << sizeof (rd) << "bytes" << endl; |
The techniques to obtain the sizes of the references are beyond the scope of this text, but I want to talk about them later. For now, I'll just say no to demonstrate that, where applicable, the size of a reference is identical to the size of a pointer.
The good part of the story is often the size of pointers and references are far less relevant than the sizes of the objects mentioned or referenced. I personally, have never needed to use that information, but for the development or on different architectures for embedded systems, since it becomes more interesting.
Using References
The use of references is already much simpler than the pointers, because operators are not required to extract addresses or de-referencing. Variable references are used as ordinary variables, noting that an operation done in a reference always affects the referenced object.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | int x, y; rx = x ; int & rx = x; ry = y ; int & y = ry; ; x = 13; ; y = 10; ; // A atribuição é automaticamente aplicada em x. rx = 42 / / The assignment is automatically applied to x. // O incremento é automaticamente aplicado em y. ry + + / / The increment is automatically applied to y. "x: " << x << endl ; // Valor de x. cout << "x:" << x << endl; / / x value. "y: " << y << endl ; // Valor de y. cout << "y:" << y << endl; / / value of y. "rx: " << rx << endl ; // Valor de rx == x. cout << "rx:" << rx << endl / / value == x rx. "ry: " << ry << endl ; // Valor de ry == y. cout << "ry:" << endl << ry / / value == y ry. |
Using such a reference is transparent to the programmer, he did not need to know that is a reference. Simply use a variable as if it were ordinary. With my limited imagination can not see how anyone could be excommunicated by using terms inappropriately. Although always have some pork spirit who can do shit with references, is much easier to take undergrowth Saci when handling pointers.
Addresses and References
From the standpoint of Murphy , the references are ugly, boring and silly, because there is little potential hazard to do with them. Even as there are many surprises address (will?). Consider the code below:
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 & rb = b; ; ra = 42; ; rb = 7; "ra = " << ra << endl ; // O valor de ra == 42. cout << "ra =" << ra << endl / / The value of ra == 42. "rb = " << rb << endl ; // O valor de rb == 7. cout << "rb =" << endl << rb / / The value of rb == 7. "a = " << a << endl ; // O valor de a == ra == 42. cout << "a =" << a << endl; / / The value of ra == a == 42. "b = " << b << endl ; // O valor de b == rb == 7. cout << "b =" << b << endl; / / The value of rb == b == 7. "&a = " << & a << endl ; // O endereço de a. cout << "& a =" << & a << endl; / / The address of a. "&b = " << & b << endl ; // O endereço de b. cout << "& b =" << & b << endl; / / The address of b. "&ra = " << & ra << endl ; // O endereço de ra == &a. cout << "& ra =" << & ra << endl / / The address ra == & a. "&rb = " << & rb << endl ; // O endereço de rb == &b. cout << "& rb =" << & rb << endl / / The address rb == & b. |
In lines 17 and 18 I declare two integer variables (could have done this with one example ...). In lines 20 and 21 I declare two references, referencing the two previous variables. From that moment the variables ra and rb are just nicknames for the variables a and b. As we saw earlier, any operator applied to the references, actually acts on the referenced objects, so each pair variable-reference always has the same value.
The interesting part to note is that the addresses of the references are exactly the same addresses of the variables they reference, unlike pointers that had their own addresses. Why? Because you fell in Topless Trickster . Remember that talk of any operator is applied to a reference? Well, the & operator used here is the "address", which is also applied directly to the original variables and not in the references. The same techniques ninja used to obtain the sizes of the references are necessary to obtain the addresses them.
Again the fun part is that the reference mechanism is designed to be as transparent as possible for the programmer. Sizes and physical addresses of references are irrelevant information from the standpoint of programming "normal" in C + +.
Differences and similarities between Pointers and References
Both pointers as references are mechanisms of indirection in C + +, ie are mechanisms used to that from a given symbol (variable) I am able to manipulate another object.
The main uses for pointers are usually related to management and dynamic handling of memory creation and destruction of objects of different shapes and special moments, as well as "passing parameters by reference" (so it quotes). Since the references are mostly used in passing by reference (I wonder why?) And operator overloading.
Basically, all we can do with references can be emulated with pointers. Already recíprocra is not always true. The great advantage of them however, is the fact become indirection completely transparent to the programmer.
An interesting allegory to help better understand the differences between pointers and references is the nickname. For example: Imagine that a person, say, Carlos Caetano Bledorn Verri , our variable is the original object. Dunga is already a reference to Carlos Caetano Bledorn Verri, it is an alias for the same object are the same person. Already the mother of Dunga (Carlos Caetano or Bledorn Verri, whatever), which is cited by contantemente crowd, can be considered a pointer to it, for certain operators of vocabulary data, made her a compliment, actually is indirectly targeted to it.
Links
- referencias.zip (all sources of the post);
- 01-declaracao.cpp
- 02-tamanhos.cpp
- 03-utilizando.cpp
- 04-enderecos.cpp
- The Guilty
Comments
- http://caloni.com.br Wanderley Caloni
- http://caloni.com.br Wanderley Caloni
- http://blabos.org blabos
- http://blabos.org blabos
- 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» Latest research in the national blogosphere
- http://www.brunodanielmarinho.com bruno
- http://www.brunodanielmarinho.com bruno
- http://blabos.pip.verisignlabs.com/ blabos
- http://blabos.pip.verisignlabs.com/ blabos
- Cairo Rocha
- http://blabos.org Blabos of Blebe

