Monday, January 17, 2011

References

References are a type of C++ variable that act as an alias to another variable. A reference variable acts just like the original variable it is referencing. References are declared by using an ampersand (&) between the reference type and the variable name:
1int nValue = 5; // normal integer
2int &rnRef = nValue; // reference to nValue
The ampersand in this context does not mean “address of”, it means “reference to”. Let’s take a look at references in use:
1nValue = 6; // nValue is now 6
2rnRef = 7; // nValue is now 7
3 
4cout << nValue; // prints 7
5nValue++;
6cout << rnRef; // prints 8
Using the address-of operator on a reference returns the address of the value being referenced:

1cout << &nValue; // prints 0012FF7C
2cout << &rnRef; // prints 0012FF7C
References are implicitly const. Like normal constant objects, references must be given a value upon declaration:
1int nValue = 5;
2int &rnRef = nValue; // valid reference
3 
4int &rnInvalidRef; // invalid, needs to reference something
Furthermore, the reference can not be “redirected” to another variable. Consider the following snippet:
1int nValue = 5;
2int nValue2 = 6;
3 
4int &rnRef = nValue;
5rnRef = nValue2; // assigns value 6 to nValue -- does NOT change the reference!
Const references
It is possible to declare a const reference. A const reference will not let you change the value it references:
1int nValue = 5;
2const int &rnRef = nValue;
3 
4rnRef = 6; // illegal -- rnRef is const
You can assign const references to literal values, though there is typically not much need to do so:
1const int &rnRef = 6;
Typical use of references
References are typically used for one of two purposes.
First, const references are often used as function parameters, which we will talk about more in the next section on functions. Because const references allow us to access but not change the value of an object, they can be used to give a function access to an object, but give assurance to the caller that the function will not change the object. This helps prevent inadvertent side effects.
Another primary use of references is to provide easier access to nested data. Consider the following struct:
01struct Something
02{
03    int nValue;
04    float fValue;
05};
06 
07struct Other
08{
09    Something sSomething;
10    int nOtherValue;
11};
12 
13Other sOther;
Let’s say we needed to work with the nValue field of the Something struct of sOther. Normally, we’d access that member as sOther.sSomething.nValue. If there are many separate accesses to this member, the code can become messy. References allow you to more easily access the member:
1int &rnValue = sOther.sSomething.nValue;
2// rnValue can now be used in place of sOther.sSomething.nValue
The following two statements are thus identical:
1sOther.sSomething.nValue = 5;
1rnValue = 5;
This can help keep your code cleaner and more readable.

No comments: