- [Instructor] C++ references are very much like pointers,
but with different rules and different semantics.
Here's working.cpp from chapter three of the exercise files,
and let's take a look at a quick example.
I'm going to go ahead and declare a variable, int i,
and give it a value.
And then I'm going to declare a reference to that,
I'll call it, ir.
And that's now a reference to i
and so I can say ir equals 10.
When I print the value of i,
(keypads clicking)
you'll see that i has been changed to 10,
because I changed it through the reference.
So reference is like a pointer,
but with significant differences.
The syntax of assigning a reference
does not involve using the address of operator.
The reference operator is used to say
that this is a reference. This is an integer reference.
But I never take the address of i
I simply assign it like that.
The syntax of getting a value referred by a reference
or of setting that value
does not include the value of dereference operator.
So here, I just set the value of the reference,
and it changes the value of the referred variable.
A reference cannot be null, it cannot be uninitialized
and it cannot be changed to refer to another variable.
So here's a common usage.
I'm going to declare a function
that returns a reference to an integer,
and it takes a reference as its argument.
First, I'm going to increment "i" and then return it.
So that's the pre-increment,
the increment before the variable.
Now I'm just going to do this.
(keypads clicking)
Let's say this is f(i) like that.
When I run this, you notice that the value is six,
and if I make this back to
just showing i,
when I run this,
you notice that i has changed to six as well.
I call the function, and it increments i.
And because i was passed as a reference,
and returned as a reference,
it's changing i, in fact,
I can do this.
When I run it, you notice that i is now 42,
because I've actually changed the value
of the returned reference.
So the usefulness of references
is that it doesn't make a copy
when you pass to a function call.
So if I have some large object,
and I want to pass it to a function call,
like an object-oriented string or library string
or something like that,
I can pass it without making a copy,
and it's more efficient that way.
The downside is that
unless you look at the function signature,
there is no way of knowing that you're passing a reference.
If I'm just looking at this,
I don't know that it's a reference
and so there's no way of knowing
that I've got these side effects.
This is called a side effect when something is changed,
and you didn't change it directly,
it's been changed indirectly.
So the solution is to use const references
as often as possible.
So I'll make that reference a const
and I'll make this reference a const.
Now none of these side effects are allowed anymore,
when I try to build,
I can't increment it because it's constant.
So I got to take that out.
And I certainly can't change the return value.
So I got to take that out.
And now none of my side effects are happening anymore,
and my integer is unchanged.
So my recommendation is to use pointers
where you want to be able to have side effects.
Use references only where you can use const.
But you need to be aware that not everybody agrees
with my opinion on this, like so many things.
And so there's a lot of code out there
that uses non-const references,
including a bit of the standard template library.
So you just need to be conscious of this effect.
References are very powerful.
They're very common in C++.
I'll be using references quite a bit,
and you'll gain much more experience with them
in the rest of this course.