A reference is a type of C++ variable that acts as an alias to another object or value. C++ supports three kinds of references:

  1. References to non-const values (typically just called “references”, or “non-const references”).
  2. References to const values (often called “const references”).
  3. C++11 added r-value references.

 

Basic Syntax

Declaring a variable as a reference rather than a normal variable simply entails appending an ampersand to the type name. When a reference is created, you must tell it which variable it will become an alias for. After you create the reference, whenever you use the variable, you can just treat it as though it were a regular integer variable. But when you create it, you must initialize it with another variable, whose address it will keep around behind the scenes to allow you to use it to modify that variable. In a way, this is similar to having a pointer that always points to the same thing.

int x;

// foo is now reference to x
int &foo = x;  

// Set x to 56
foo = 56;
std::cout <<x;

 

References to non-const values

A reference (to a non-const value) is declared by using an ampersand (&) between the reference type and the variable name:

int value = 5; // normal integer
int &ref = value; // reference to variable value

// References to non-const values can only be initialized with non-const l-values.
// They can not be initialized with const l-values or r-values.
const int y = 7;
int &ref2 = y; // not okay, y is a const l-value

int &ref3 = 6; // not okay, 6 is an r-value

// Once initialized, a reference can not be changed to reference another variable.
int value1 = 5;
int value2 = 6;
 
int &ref = value1; // okay, ref is now an alias for value1
ref = value2; // assigns 6 (the value of value2) to value1

In this context, the ampersand does not mean “address of”, it means “reference to”. References to non-const values are often just called “references” for short.

Reference to const value

Just like it’s possible to declare a pointer to a const value, it’s also possible to declare a reference to a const value. This is done by declaring a reference using the const keyword. References to const values are often called “const references” for short.

const int value = 5;
const int &ref = value; // ref is a reference to const value

Unlike references to non-const values, which can only be initialized with non-const l-values, references to const values can be initialized with non-const l-value, const l-values, and r-values.

int x = 5;
const int &ref1 = x; // okay, x is a non-const l-value
 
const int y = 7;
const int &ref2 = y; // okay, y is a const l-value
 
const int &ref3 = 6; // okay, 6 is an r-value

 

References as function parameters

References are most often used as function parameters. In this context, the reference parameter acts as an alias for the argument, and no copy of the argument is made into the parameter. This can lead to better performance if the argument is large or expensive to copy. Because the reference parameter acts as an alias for the argument, a function that uses a reference parameter is able to modify the argument passed in.

// ref is a reference to the argument passed in, not a copy
void changeN(int &ref)
{
  ref = 6;
}

References used as function parameters can also be const. This allows us to access the argument without making a copy of it, while guaranteeing that the function will not change the value being referenced.

// ref is a const reference to the argument passed in, not a copy
void changeN(const int &ref){
  ref = 6; // not allowed, ref is const
}

 

Returning values by reference

A C++ function can return a reference in a similar way as it returns a pointer. When a function returns a reference, it returns an implicit pointer to its return value. When returning a reference, be careful that the object being referred to does not go out of scope. So it is not legal to return a reference to local var. But you can always return a reference on a static variable.

int& func() {
  int q;
  //! return q; // Compile time error
  
  static int x;
  return x;     // Safe, x lives outside this scope
}

 

 

References vs Pointers

References are often confused with pointers but three major differences between references and pointers are

  1. You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.
  2. Once a reference is initialized to an object, it cannot be changed to refer to another object. Pointers can be pointed to another object at any time.
  3. A reference must be initialized when it is created. Pointers can be initialized at any time.
  4. Reference is automatically dereferenced while * is used to dereference a pointer.