C++ Notes to Self: Reference Variables
In C++ a reference is an alternative name or an alias for a variable. It is created with an ampersand operator (&) and always needs to be initialized with a referent. The referent has to be a variable, not a literal. Once delcared this way, a reference is permanently bound to it referent variable.
Like a pointer, a reference can be used to access a variable. However, unlike a pointer, no new variable is allocated for a reference. Here are the differences between reference and pointer:
- Reference alays needs an initializer. For pointers this is optional.
- The reference initializer should be a variable, an
l-value
. The initializer of a pointer need not be anl-value
. It could be a literal representing a memory address. - A reference can never take the value of
nullptr
. A pointer can. - When a reference is created, it is bound to its referent. A pointer can be freely re-assigned to any variable of the appropriate type.
- Becasue a reference is a synonym, it does not require storage as does a pointer, which is a variable. A pointer variable has a distinct memory address. The reference shares the memory address of its referent (memory storage).
- To access the relevant data, we need a dereference operator for pointers. With references no special operator is involved.
When it comes to functions and passing parameters by value, pointers and references offer the same semantics. (See the ptr_exchange()
and ref_exchange()
usage below.) But references have the advantage of clearer semantics. The absence of address and deference pointers removes the possibility of typo mistakes.
There is also the matter of null value parameters. With a pointer function parameter, we could pass a null adddress parameter, with the caveat that we face a possible access value exception during run time. If we tried to pass a null address (nullptr
) to a function parameter that is a reference, the compiler will quickly flag this as an error.
#include <iostream>
using namespace std;
void ptr_exchange(int *a, int *b);
void ref_exchange(int &a, int &b);
int main(int argc, char **argv) {
int x = 10;
int &ref = x;
cout << &x << endl;
cout << &ref << endl;
cout << x << endl;
cout << ref << endl;
int a = 111;
int b = 222;
cout << a << "\t" << b << endl;
ptr_exchange(&a, &b);
cout << a << "\t" << b << endl;
int w = 333;
int z = 444;
cout << w << "\t" << z << endl;
ref_exchange(w, z);
cout << w << "\t" << z << endl;
return 0;
}
void ptr_exchange(int *a, int *b) {
int temp = *b;
*b = *a;
*a = temp;
}
void ref_exchange(int &a, int &b) {
int temp = b;
b = a;
a = temp;
}