Hello, I’m Liang Tang.

This is part 32 of the EasyC++ series on the use of references.

If you want a better reading experience, you can visit github repository: EasyLeetCode.

reference

References are a new feature of C++, not C.

A reference is an alias for a defined variable, which can be simply interpreted as a nickname for the same variable. Since it is a nickname or alias, it obviously has the same effect as the original variable name. So we change the alias, and the original variable value changes as well.

We use the symbol & to indicate a reference, as in the example below, where we create a reference b to variable A.

int a = 3;
int &b = a;
b++;
cout << a << endl;
Copy the code

Since b is a reference to A, they are essentially the same variable with a different name. So if we change b, it’s the same thing as changing A. So the output is 4.

That is, we need to treat the reference variable and the original variable as if they were the same variable with a different name, and if one of them changes, the other will still be in effect.

It looks a bit like a pointer, because creating a pointer can have a similar effect:

int a = 3;
int *p = &a;

*p++;
cout << a << endl;
Copy the code

But there are still some differences between references and Pointers. This question is often asked in C++ related interviews as part of the basic skills test.

The first difference is that a reference must be initialized at the time it is declared; it cannot be declared and then assigned:

int *pt; 	/ / legal
int &b;		/ / illegal
Copy the code

In this sense, a reference is closer to a const pointer, and once associated with a variable can’t point to another variable:

int &b = a;
/ / equivalent to the
int *const pt = &a;
Copy the code

In this case, b is the same thing as star pt.

If we print the address of the reference and the original variable, we get the same result:

int a = 3;
int &b = a;

cout << &a << "" << &b << endl;
Copy the code

Function reference passing

There is a problem with creating a reference to a variable since references are aliases and we already have the original variable name to use.

So references are not created for sequentially executed logic, and one of the most common use cases is when a function is passed arguments and the variable type received by the function can be set to reference. Such as:

void swap1(int& a, int& b) {
    int temp = b;
    b = a;
    a = temp;
}

void swap2(int a, int b) {
    int temp = b;
    b = a;
    a = temp;
}
Copy the code

We created two swap functions, one of which passed a reference and the other just plain passed values. If you call these two functions separately, you will find that swap2 does not work.

Because when the value is passed, there is a copy, which means that the function is actually receiving a copy of the variable. Whatever changes we make to the copy will not affect the original value, unlike passing a reference. As mentioned earlier, references are equivalent to original variables. Modifying a reference is equivalent to modifying the original variable.

In this way, we can modify the parameters passed in from inside the function body. In some special situations, it’s very convenient. For complex tree data structures, references can make writing code much easier.

In addition, there is another advantage to using a reference, since the reference we pass is equivalent to the original value. This saves the overhead of copying variables, which is fine if we pass variables like ints and doubles. Passing by reference can bring significant efficiency gains if we pass a container containing a large number of elements, such as vector,set,map, etc., and also reduces the memory overhead.