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 adding the character & (ampersand or ampersand) after the name of the type of reference. Note that the same way as the declaration of pointers, we are treating the & character as an agency 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 following line generates a / / Compilation error. You could tell why? r1, & r2 ; int & r1, & r2;
While in C + + references remind some pointers, they are quite different. Contrary to 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 "playboy lost, lost!". The only exception to this rule is for reference declared as extern, as they will be initialized at some other point of the program, but that's another rant.
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 noted that it is not used, you can even remove it from the list of symbols. But if it is used in any part of the program, the linker will laugh at your face laughing "undefined reference to 'nome_da_variavel'. So do things nicely. Stated a reference? So iniclalize it. extern? Are you sure you know what you're doing?
The logic behind this is that a reference was intended 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 to initialize a reference is not to assign a value to it. As prório Bjarne says, no operator operates on terms, 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 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 object that 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; |
Techniques for the sizes of the references are beyond the scope of this text, but I want to talk about them in the future. For now, I'll just say no to show 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 sizes of the referenced or pointed objects. I personally never had 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 done in a reference always affect the object referenced.
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 & ry = y; ; x = 13; ; y = 10; ; // A atribuição é automaticamente aplicada em x. rx = 42 / / The award 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. court << "x:" <<x <<endl; / / value of x. "y: " << y << endl ; // Valor de y. court << "y:" <<y <<endl; / / value of y. "rx: " << rx << endl ; // Valor de rx == x. court << "rx:" <<rx <<endl; / / value == x. rx "ry: " << ry << endl ; // Valor de ry == y. court << "ry:" <<ry <<endl; / / Value ry == y. |
Using a reference is as transparent to the programmer, he did not need to know that is a reference. Simply use it like a regular variable. With my limited imagination can not see how someone can be excommunicated for using terms inappropriately. Although always have some spirit of pig that can do shit with references, is much easier to get tripped up by Saci to handle pointers.
Addresses and References
From the point of view of Murphy, the references are ugly, boring and silly, because there is little potential hazard to do with them. Even as the address there are many surprises (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 << "r =" <<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. |
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. Thereafter the variables ra and rb are just aliases for the variables a and b. As mentioned above, any operator applied to the references actually operates on the referenced objects, so each pair variable-reference always has the same value.
The interesting thing 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 to apply to a reference? Well, here used the & operator 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 is 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 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 and shapes for special occasions, as well as "passing parameters by reference" (so quoted it). Since references are more used to passing by reference (why is it?) And operator overloading.
Basically, all we can do with references can be emulated with pointers. On the other 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, it is an alias for the same object are the same person. Already the mother of Dunga (or Dunga, whatever), which is cited by the steady hand fans, can be considered a pointer to it, because some providers of data vocabulary, made a compliment to her, the truth is indirectly targeted him.
Links
- referencias.zip (all sources of post);
- 01-declaracao.cpp
- 02-tamanhos.cpp
- 03-utilizando.cpp
- 04-enderecos.cpp
- The Guilty
Comments
5 Responses to "Pointers and references in C + + Part 2"
Leave a Reply



Great article!
Unfortunately, the references are not as harmless as they seem. Imagine the following situations:
1. Someone returns a reference to a local variable non-static:
In this case the scope ends even before someone uses the reference.
The solution is to get a reference as a parameter and make only one copy: for the variable "out".
2. Someone wants to use dynamic memory as ordinary variables:
These examples seem beast, but not as improbable as they seem. Just the code to be sanitized with Design Patterns or any other nonsense and it explodes without you knowing what happened.
[] s
Caloni, you're a guy too hasty
Yes, you're absolutely right. But I let it go on purpose.
I also have not spoken yet to const pointers or references, or even that association between pointers and arrays, but I will speak.
Thanks for the compliment, it is very motivating.
Abração
My naivete, that I thought I had given it quits when you said "From the point of view of Murphy, the references are ugly, boring and silly, because there is little potential hazard to do with them." In any way already recommended your article to a beginner, because it is actually very well explained for those who are venturing for the differences between C and C + +.
I await the proceedings.
[] s
Partner blab!
Congratulations for the article, VERY good!
[] s
[...] [...] Pointeiros and References