Professional C__ - Marc Gregoire [134]
Modifying References
A reference always refers to the same variable to which it is initialized; references cannot be changed once they are created. This rule leads to some confusing syntax. If you “assign” a variable to a reference when the reference is declared, the reference refers to that variable. However, if you assign a variable to a reference after that, the variable to which the reference refers is changed to the value of the variable being assigned. The reference is not updated to refer to that variable. Here is a code example:
int x = 3, y = 4;
int& xRef = x;
xRef = y; // Changes value of x to 4. Doesn't make xRef refer to y.
Code snippet from References\ReferenceVariables.cpp
You might try to circumvent this restriction by taking the address of y when you assign it:
int x = 3, y = 4;
int& xRef = x;
xRef = &y; // DOES NOT COMPILE!
This code does not compile. The address of y is a pointer, but xRef is declared as a reference to an int, not a reference to a pointer.
Some programmers go even further in attempts to circumvent the intended semantics of references. What if you assign a reference to a reference? Won’t that make the first reference refer to the variable to which the second reference refers? You might be tempted to try this code:
int x = 3, z = 5;
int& xRef = x;
int& zRef = z;
zRef = xRef; // Assigns values, not references
Code snippet from References\ReferenceVariables.cpp
The final line does not change zRef. Instead, it sets the value of z to 3, because xRef refers to x, which is 3.
You cannot change the variable to which a reference refers after it is initialized; you can only change the value of that variable.
References to Pointers and Pointers to References
You can create references to any type, including pointer types. Here is an example of a reference to a pointer to int:
int* intP;
int*& ptrRef = intP;
ptrRef = new int;
*ptrRef = 5;
Code snippet from References\ReferenceVariables.cpp
The syntax is a little strange: You might not be accustomed to seeing * and & right next to each other. However, the semantics are straightforward: ptrRef is a reference to intP, which is a pointer to int. Modifying ptrRef changes intP. References to pointers are rare, but can occasionally be useful, as discussed in the “Reference Parameters” section later in this chapter.
Note that taking the address of a reference gives the same result as taking the address of the variable to which the reference refers. For example:
int x = 3;
int& xRef = x;
int* xPtr = &xRef; // Address of a reference is pointer to value
*xPtr = 100;
Code snippet from References\ReferenceVariables.cpp
This code sets xPtr to point to x by taking the address of a reference to x. Assigning 100 to *xPtr changes the value of x to 100. Writing a comparison “xPtr == xRef” will not compile because of a type mismatch; xPtr is a pointer to an int while xRef is a reference to an int. The comparisons “xPtr == &xRef” and “xPtr == &x” both compile without errors and are both true.
Finally, note that you cannot declare a reference to a reference or a pointer to a reference:
int x = 3;
int& xRef = x;
int&& xDoubleRef = xRef; // DOES NOT COMPILE!
int&* refPtr = &xRef; // DOES NOT COMPILE!
Code snippet from References\ReferenceVariables.cpp
In this example && is used in an attempt to declare a reference to a reference which is not possible. However, the C++11 standard assigns a new meaning to &&. It now means rvalue reference and is discussed later in this chapter.
Reference Data Members
As Chapter 7 explains, data members of classes can be references. A reference cannot exist without referring to some other variable. Thus, you must initialize reference data members in the constructor initializer, not in the body of the constructor. The following is a quick example:
class MyClass
{
public:
MyClass(int& ref) : mRef(ref) {}
protected:
int& mRef;
};
int main()
{
int i = 123;
MyClass m(i);
return 0;
}
Code snippet from References\ReferenceDataMembers.cpp
Consult Chapter 7 for details.
Reference