WEBVTT

00:00:00.340 --> 00:00:05.170
As I mentioned, there is an easier way to pass objects by reference in C++.

00:00:05.290 --> 00:00:09.390
Let's remove all of the asterisk characters to turn this pointer back into a

00:00:09.390 --> 00:00:13.480
simple integer and also to stop dereferencing this variable.

00:00:13.580 --> 00:00:16.440
I will also remove the & character because I'm no

00:00:16.440 --> 00:00:18.760
longer interested in the address of x.

00:00:19.040 --> 00:00:22.740
This is now the same program we had at the beginning of the previous lesson.

00:00:22.740 --> 00:00:26.960
And if you remember, this program will pass the argument by value.

00:00:26.960 --> 00:00:32.400
To pass it by reference in C++, there is only one simple thing you need to do.

00:00:32.400 --> 00:00:36.460
Just add the & character before the name of the parameter.

00:00:37.740 --> 00:00:42.150
Okay, let's try to compile the program again, and it worked.

00:00:42.150 --> 00:00:44.950
As you can see, the last number is still 8,

00:00:44.950 --> 00:00:47.790
which means that the value from the main function's variable,

00:00:47.800 --> 00:00:49.700
x, was also changed.

00:00:49.700 --> 00:00:54.180
And as you know, that means that we passed the reference of an argument.

00:00:54.180 --> 00:00:57.960
But how does this work, and what did we actually do here?

00:00:57.960 --> 00:00:59.560
Let's go step by step.

00:01:00.140 --> 00:01:03.950
C++ allows us to use the so‑called references.

00:01:03.980 --> 00:01:06.610
You can think of references in two ways.

00:01:06.710 --> 00:01:09.550
The first way is to imagine that they are just pointers,

00:01:09.550 --> 00:01:11.270
which are immediately dereferenced,

00:01:11.270 --> 00:01:14.060
so you don't have to use the dereference operator.

00:01:14.340 --> 00:01:17.320
But I think that this is just making the whole matter more confusing,

00:01:17.320 --> 00:01:21.360
so let me create a reference, and we can see what is actually going on in memory.

00:01:21.640 --> 00:01:26.550
I declared a simple integer variable and initialized it to the number 5.

00:01:26.550 --> 00:01:29.900
On the next line, I'm creating a reference, y.

00:01:29.900 --> 00:01:33.920
The reason you know that this is a reference and not a regular variable is

00:01:33.920 --> 00:01:37.240
because of this & character in front of the identifier.

00:01:37.240 --> 00:01:40.320
Just like we created pointers by adding the asterisk,

00:01:40.320 --> 00:01:43.760
we create references by adding the & character.

00:01:44.340 --> 00:01:47.470
The best way to think about references is to consider

00:01:47.470 --> 00:01:50.280
them as an alias for another variable.

00:01:50.430 --> 00:01:55.050
In other words, our reference is just another name for the same place in memory.

00:01:56.140 --> 00:01:58.840
In this case, we are saying create the reference,

00:01:58.840 --> 00:02:02.690
y, and assign it to the place in memory held by the variable,

00:02:02.690 --> 00:02:03.250
x.

00:02:04.440 --> 00:02:05.500
To demonstrate this,

00:02:05.510 --> 00:02:08.160
I will print out the value from both variables and

00:02:08.160 --> 00:02:13.850
then increment each one of them, and then I will again print out the values.

00:02:15.840 --> 00:02:17.970
Let's compile this.

00:02:17.970 --> 00:02:22.120
Both of the variables give us the number 5 at first,

00:02:22.130 --> 00:02:24.720
and then after incrementing each one of them,

00:02:24.720 --> 00:02:28.200
both of them have the number 7, and this makes sense.

00:02:28.440 --> 00:02:32.010
As you can see, you can use a reference just like any other variable.

00:02:32.020 --> 00:02:35.710
You just have to remember that a reference doesn't have its own place in memory.

00:02:35.720 --> 00:02:38.660
It is used as a second name for another variable.

00:02:38.940 --> 00:02:40.740
So when you create a reference,

00:02:40.740 --> 00:02:43.760
you need to assign it to another variable immediately.

00:02:43.940 --> 00:02:46.630
A reference cannot be null like a pointer.

00:02:46.870 --> 00:02:49.210
Don't confuse references with pointers.

00:02:49.210 --> 00:02:51.950
You can reassign a pointer to another address,

00:02:51.950 --> 00:02:56.570
but you cannot reassign a reference because a reference already dereferenced.

00:02:56.570 --> 00:02:59.560
It will always point to the same place in memory.

00:03:01.040 --> 00:03:03.720
What do you think will happen if I print out the address of the

00:03:03.720 --> 00:03:07.060
variable x and the address of the y reference?

00:03:07.640 --> 00:03:10.250
Do you think that these addresses will be different?

00:03:11.740 --> 00:03:12.760
Let's compile it.

00:03:14.040 --> 00:03:17.910
And it seems that the reference, y, has the same address as the variable,

00:03:17.910 --> 00:03:21.560
x, which makes sense because they point to the same place in memory.

00:03:23.240 --> 00:03:26.460
These two contexts in which this character appears are

00:03:26.470 --> 00:03:29.260
actually really hard to mistake for one another.

00:03:30.040 --> 00:03:32.270
You will always know that this refers to the reference

00:03:32.270 --> 00:03:35.210
declaration because you are declaring a reference.

00:03:35.240 --> 00:03:38.000
It makes no sense that you are trying to find an address of

00:03:38.000 --> 00:03:40.560
a variable that you have just created.

00:03:40.570 --> 00:03:42.790
And also, this is an lvalue.

00:03:42.800 --> 00:03:45.660
We'll talk about this in one of the following modules.

00:03:45.840 --> 00:03:46.800
But basically,

00:03:46.810 --> 00:03:50.210
you will never see a reference operator on the left side because you

00:03:50.210 --> 00:03:53.160
cannot assign something else to a memory address.

00:03:54.140 --> 00:03:57.560
And now, let's get back to the first example from the lesson.

00:03:57.560 --> 00:04:00.250
This code now makes more sense.

00:04:00.940 --> 00:04:04.760
Instead of declaring a regular variable or a pointer as a parameter,

00:04:04.760 --> 00:04:08.190
this parameter is now defined as a reference.

00:04:08.200 --> 00:04:11.900
So when we pass the variable x from the main function here,

00:04:11.910 --> 00:04:16.910
this reference will become another name for that same place in memory,

00:04:16.910 --> 00:04:20.920
even though this variable is in another scope.

00:04:20.920 --> 00:04:23.490
And since this is just another name,

00:04:23.490 --> 00:04:27.400
we don't have to use the dereference operator here to modify the data.

00:04:27.400 --> 00:04:31.840
As you can see, this code looks much more cleaner and more readable.

00:04:31.850 --> 00:04:34.720
It prevents you from making mistakes like forgetting

00:04:34.720 --> 00:04:36.450
to make this variable a pointer,

00:04:36.450 --> 00:04:40.460
passing an address or dereferencing a pointer inside of a function.

00:04:40.740 --> 00:04:44.340
This code in compiled assembly will look basically the same

00:04:44.340 --> 00:04:46.460
as the one we wrote with the pointers.

00:04:46.740 --> 00:04:49.920
So you can think of references as a syntactic sugar,

00:04:49.920 --> 00:04:51.710
which makes the code look cleaner.

00:04:51.740 --> 00:04:55.050
Passing by reference is a very common occurrence in programming,

00:04:55.050 --> 00:04:58.930
and this approach makes it so much more simple than using pointers.

00:04:58.940 --> 00:05:01.820
I would usually cover this feature in the last module,

00:05:01.830 --> 00:05:05.500
but this one is so useful and convenient that it simply makes no

00:05:05.500 --> 00:05:08.250
sense to keep using pointers in this context,

00:05:08.340 --> 00:05:11.340
not even as a learning tool, because in C++,

00:05:11.340 --> 00:05:15.040
you will always use references to pass arguments by a reference.

00:05:15.140 --> 00:05:17.530
This is not really that important when working with

00:05:17.530 --> 00:05:19.320
primitive values like integers,

00:05:19.330 --> 00:05:23.960
but we will use references with user‑defined objects in the following modules.
