C++ References

In C++, a reference is a special type of variable, that is an alias, or additional name, for another variable. Once created, both the alias and the original variable name can be used to refer to and alter the same value. Unlike pointers, a reference cannot be null, it must be initialised when it is defined and cannot be changed later to refer to a different variable.

The example below declares and initialises a variable ‘age’, of type ‘int’ and sets it to 30. The second line declares a reference called ‘personAge’, again of type ‘int’ and initialises it to the variable ‘age’. A reference must be of the same type as the variable it is referring to.

int age = 30;
int &personAge = age;

The ampersand is what denotes the second variable as a reference. It should be noted that the ampersand can immediately follow the type, in this case ‘int’, be on its own between the variable type and name, or just before the variable name, as in the above example. All three of the below examples are a valid way of declaring and initialising the reference ‘personAge’.

int& personAge = age;
int & personAge = age;
int &personAge = age;

Once a reference has been declared and initialised, the value can be accessed through the original variable or the reference.

cout << age << endl;
cout << personAge << endl;

Here, the value 30 is output to the console in both instances. Similarly, the value can be updated using the original variable or the reference.

age += 1;
personAge += 1;

References are often utilised in range-based ‘for’ loops, which are used to loop through data structures such as arrays and vectors. If a reference is not used, then any alterations to the structure being looped through, only exists for the duration of the loop. This is because when a vector, for example, is used in a range-based ‘for’ loop, without a reference, a copy of the vector is made, so any changes are made to the copy and not the original. This is demonstrated below.

The vector, names, is declared and initialised with four values. The first loop checks to see if the name is equal to ‘Fred’ and changes it to ‘Frieda’ if it is, then displays the name. The second loop just goes through the vector, displaying the names in the console.

vector<string> names = {
    "Bob",
    "George",
    "Fred",
    "Alan"
};

for (string name: names)
{
    if (name == "Fred")
    {
        name = "Frieda";
    }
    cout << name << endl;
}

cout << endl;

for (string name: names)
{
    cout << name << endl;
}

The resulting output from this shows that the name ‘Fred’ has been changed to ‘Frieda’ in the first loop, but because a reference isn’t used, the change is only present in the copy of the vector. This means that when the names are displayed in the second loop, ‘Fred’ is output.

Bob
George
Frieda
Alan

Bob
George
Fred
Alan

If a reference is used in the first range-based ‘for’ loop, it has the effect of updating the name in the original vector, because a copy isn’t being used.

vector<string> names = {
    "Bob",
    "George",
    "Fred",
    "Alan"
};

for (string &name: names)
{
    if (name == "Fred")
    {
        name = "Frieda";
    }
    cout << name << endl;
}

cout << endl;

for (string name: names)
{
    cout << name << endl;
}

The output now shows the name ‘Frieda’ in both sets of names.

Bob
George
Frieda
Alan

Bob
George
Frieda
Alan

Another major use of references is with functions, to allow for a parameter to be passed by reference, instead of by value. Functions are discussed in the next section.