Comparison of references and pointers in C++

References are a concept in C++. Beginners tend to confuse references with pointers.

In the following program, n is a reference to m, and m is the referent.

int m; 
int &n = m; 

n is equivalent to an alias (nickname) for m. Any operation on n is an operation on m.

So n is neither a copy of m nor a pointer to m; in fact, n is m itself.

Rules for references:

  • (1) A reference must be initialized when it is created (a pointer can be initialized at any time).
  • (2) There can be no NULL reference; a reference must be associated with a valid storage unit (a pointer can be NULL).
  • (3) Once a reference is initialized, the reference relationship cannot be changed (a pointer can change the object it points to at any time).

In the following example program, k is initialized as a reference to i.

The statement k = j does not modify k to become a reference to j; it only changes k's value to 6.

Since k is a reference to i, the value of i also becomes 6.

int i = 5; 
int j = 6; 
int &k = i; 
k = j; // k 和 i 的值都变成了 6;

The main function of references is to pass function parameters and return values.

In C++, there are three ways to pass function parameters and return values: value passing, pointer passing, and reference passing.

The following is an example program of "value passing".

Since x inside the Func1 function body is a copy of the external variable n, changing the value of x does not affect n, so the value of n remains 0.

void Func1(int x) 
{ 
    x = x + 10; 
} 
... 
int n = 0; 
Func1(n); 
cout << "n = " << n << endl; // n = 0 

The following is an example program of "pointer passing".

Since x inside the Func2 function body is a pointer to the external variable n, changing the content pointed to by the pointer will cause the value of n to change, so the value of n becomes 10.

void Func2(int *x) 
{ 
    (* x) = (* x) + 10; 
} 
... 
int n = 0; 
Func2(&n); 
cout << "n = " << n << endl; // n = 10 

The following is an example program of "reference passing".

Since x inside the Func3 function body is a reference to the external variable n, x and n are the same thing. Changing x is equivalent to changing n, so the value of n becomes 10.

void Func3(int &x) 
{ 
    x = x + 10; 
} 
... 
int n = 0; 
Func3(n); 
cout << "n = " << n << endl; // n = 10

Comparing the above three example programs, you will find that "reference passing" behaves like "pointer passing" but is written like "value passing".

In fact, anything that "references" can do, "pointers" can also do. Why do we still need "references"?

The answer is "use the right tool for the right job."

Pointers can manipulate anything in memory without constraints. Although pointers are powerful, they are very dangerous.

If you really just need to borrow an "alias" for an object, then use a "reference" instead of a "pointer" to avoid accidents.