Pointers and references in C + + part 2
Continuing with this attempt to 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 5.5 of his book , whose content is so good that I only notice now 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 appending 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 treating the & character as a rating and not an operator. There is an operator declaration of pointers or references. It's just a notation of the language. Given a type T, the expression means T & T Reference. For example:
/ / 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 of references must be the same / / The variables referenced. ra = i ; int & ra = i; rb = i ; int rb = & i; rc = i ; int & rc = i; / / Unlike pointers, the line below generates a / / Compilation error. You could tell why? r1, & r2 ; int & r1, & r2;
While in C + + references remind some pointers, they are quite different. Unlike what happens with pointers, a reference must be initialized in 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 , as they will be initialized at any other point of the program, but that's another conversation.
If you try to cheat by declaring an extern reference without initializing it the compiler will not complain. If it is never used, ok. If the compiler is smart and notice that it will not be used, it can even remove it from the list of symbols. But if it is used anywhere in the program, the linker will laugh at your face, laughing, "undefined reference to 'nome_da_variavel'." So do things right. Declared a reference? So iniclalize it. extern? Are you sure you know what you're doing?
The logic behind this is that a reference was planned to be a name for something. If you do not boot, it will not name for nothing, then it makes sense. One very important detail is that starting a reference is not to assign a value to it. As the 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 always reference 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, since when applying the sizeof operator on a reference, we are actually applying the operator on the object to which it references, 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 ; court <<"Size of char:" <<sizeof (c) <<"bytes" <<endl; "Size of int: " << sizeof ( i ) << " bytes" << endl ; court <<"Size of int:" <<sizeof (i) <<"bytes" <<endl; "Size of double: " << sizeof ( d ) << " bytes" << endl ; court <<"Size of double:" <<sizeof (d) <<"bytes" <<endl; endl ; court <<endl; "Size of char&: " << sizeof ( rc ) << " bytes" << endl ; court <<"Size of char &:" <<sizeof (rc) <<"bytes" <<endl; "Size of int&: " << sizeof ( ri ) << " bytes" << endl ; court <<"Size of int &:" <<sizeof (ri) <<"bytes" <<endl; "Size of double&: " << sizeof ( rd ) << " bytes" << endl ; court <<"Size of double &:" <<sizeof (rd) <<"bytes" <<endl; |
The techniques for obtaining the sizes of the references are beyond the scope of this text, but I intend to talk about them later. For now, I'll just say without showing that, where applicable, the size of a reference is identical to the size of a pointer.
The good part of the story is that often the sizes of pointers and references are far less relevant than the size of the object pointed or referred. I particularly never needed to use that information, but for the development or on different architectures for embedded systems, it has become more interesting.
Using References
The use of references is now much simpler than the pointers, because operators are not required to extract addresses or de-referencing. Variable references are used as common variables, noting that an operation performed on a reference always affect the object referenced.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | int & rx = x ; int & ry = y ; x = 13 ; y = 10 ; rx = 42 ; // A atribuição é automaticamente aplicada em x. ry ++ ; // O incremento é automaticamente aplicado em y. cout << "x: " << x << endl ; // Valor de x. cout << "y: " << y << endl ; // Valor de y. cout << "rx: " << rx << endl ; // Valor de rx == x. cout << "ry: " << ry << endl ; // Valor de ry == y. int x, y, int & rx = x; int & ry = y, x = 13, y = 10, rx = 42 / / The award is automatically applied at x. ry + + / / The increment is automatically applied in y. court <<"x:" <<x <<endl / / value of x. court <<"y:" <<y <<endl / / value of y. court <<"rx" <<rx <<endl / / Value Rx == x. court <<"ry:" <<ry <<endl / / Value ry == y. |
Using a reference is as transparent to the programmer, he does not need to know that is a reference. Just use like an ordinary variable. With my limited imagination can not see how someone can be excommunicated for using terms inappropriately. Although always have some spirit pig who can do shit with references, is much easier to get tripped up by Saci to handle 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. court <<"ra =" <<ra <<endl / / The value of ra == 42. "rb = " << rb << endl ; // O valor de rb == 7. court <<"rb =" <<rb <<endl / / The value of rb == 7. "a = " << a << endl ; // O valor de a == ra == 42. court <<"a =" <<a <<endl / / The value of the ra == == 42. "b = " << b << endl ; // O valor de b == rb == 7. court <<"b =" <<b <<endl / / The value of b rb == == 7. "&a = " << & a << endl ; // O endereço de a. court <<"& a =" <<& a <<endl / / The address of a. "&b = " << & b << endl ; // O endereço de b. court <<"& b =" <<& b <<endl / / The address of b. "&ra = " << & ra << endl ; // O endereço de ra == &a. court <<"& ra =" <<& ra <<endl / / The address of ra == & a. "&rb = " << & rb << endl ; // O endereço de rb == &b. court <<"& rb =" <<& rb <<endl / / The address of rb == & b. |
On lines 17:18 I declare two integer variables (could have done this with one example ...). On lines 20:21 I declare two references, referencing the two previous variables. Thereafter the variables ra and rb are just aliases for the variables a and b. As we saw earlier, any operator applied to the references actually operates 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 Pegadinha do Malandro . Remember that talk of any operator is applied to a reference? Well, the & operator used here is the "address" which is also applied directly on the original variables and not in the references. The same techniques used ninja to get the sizes of the references are necessary to obtain the addresses of them.
Again the fun part is that the reference mechanism was designed to be as transparent as possible to the programmer. Sizes and physical addresses of references are irrelevant information from the point of view of 'normal' program in C + +.
Differences and similarities between pointers and references
Both pointers and references are mechanisms of indirection in C + +, or mechanisms are used to that from a given symbol (variable) I will be able to manipulate another object.
The main uses for pointers are generally related to management and manipulation of dynamic memory, creation and destruction of objects of different shapes and special moments as well as "passing parameters by reference" (so quoted it). References are already being used in passing by reference (why?) And operator overloading.
Basically, all we can do with references can be emulated with pointers. Already reciprocally is not always true. The great advantage of them, however, is that the indirection become 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, Dunga , is our original variable, the object. Dunga is already a reference to Dunga, since it is an alias for the same object are the same person. Already the mother of Dunga (or Dunga, whatever), which is as long cited by the crowd, can be considered a pointer to it, because certain data operators vocabulary, made her a compliment, actually is indirectly targeted him.
Links
- referencias.zip (all sources of the post);
- 01-declaracao.cpp
- 02-tamanhos.cpp
- 03-utilizando.cpp
- 04-enderecos.cpp
- The Guilty
Comments
- blab
- bruno
- Jorge Pereira
- Wanderley Caloni
- Wanderley Caloni
- blab


