WEBVTT

00:00.150 --> 00:00.690
Hello again!

00:00.900 --> 00:04.410
In this video, we are going to look at prefix and postfix operators.

00:05.610 --> 00:08.580
C++ has two versions of the increment operator.

00:09.450 --> 00:14.520
The prefix version has the "++" before the argument, the object that is going to be incremented.

00:15.150 --> 00:21.750
This will add one to the argument and return the new value. For the postfix version,

00:21.810 --> 00:28.500
the "++" comes after the object, and this will add one to it and then return the original object.

00:29.070 --> 00:34.500
So this will make a copy of the object, before it modifies it, and then returns the copy of the original

00:34.500 --> 00:34.980
object.

00:36.240 --> 00:42.360
This was actually a single processor instruction, on the computer on which C was developed, and the inventors

00:42.360 --> 00:45.870
of C thought it might be useful to have this operator in their language.

00:47.560 --> 00:52.780
They are also prefix and postfix decrement operators which work the same way, except they subtract

00:52.780 --> 00:53.950
one instead of adding one.

00:57.380 --> 01:04.640
If we have a pointer to an element of an array, then the "++" operator will increment the pointer,

01:05.210 --> 01:07.220
and that will move it to the next element.

01:07.640 --> 01:13.730
So if we have a pointer to the first element of an array, and we increment it, then the pointer

01:13.730 --> 01:16.640
will now be pointing to the second element in the array.

01:19.840 --> 01:21.190
And something that we have all done.

01:21.490 --> 01:27.370
We can use this for iterating over the elements of an array. So we get a pointer to the first element.

01:27.970 --> 01:32.980
If we use the name of an array where a pointer is expected, we get a pointer to the first element.

01:33.950 --> 01:39.980
And then we can iterate over the elements of the array. We can dereference this pointer to get the current

01:39.980 --> 01:45.320
element, and then do something with it, and then we increment the pointer at the end of the loop, to

01:45.320 --> 01:46.820
go on to the next element.

01:47.750 --> 01:54.200
And we can write similar code with iterators and container elements. So we can increment iterators to step through

01:54.200 --> 01:55.370
the elements of the container.

01:57.600 --> 02:02.160
So here we are writing the dereference and the increment as two separate statements.

02:04.820 --> 02:06.320
With the postfix operator,

02:06.320 --> 02:10.090
we can write it all in one single statement, like this.

02:10.100 --> 02:11.090
So star,

02:11.090 --> 02:11.390
"p", ++.

02:11.390 --> 02:16.430
The increment has a higher operator precedence than the dereference.

02:17.030 --> 02:23.000
So this will increment "p", return the original value and then dereference this original value.

02:24.370 --> 02:30.490
So if "p" is pointing to the first element, this will move "p" to the second element, but it will

02:30.490 --> 02:31.990
dereference the first element.

02:33.930 --> 02:39.410
If you are writing a for loop, and you use the increment operator to increase the loop counter,

02:39.750 --> 02:41.880
then you can use either version of the operator.

02:42.720 --> 02:47.610
I remember actually, when I was learning C, many years ago, I read a book which said that the prefix

02:47.610 --> 02:52.650
operator increment at the start of the loop and the postfix operator increments at the end of the

02:52.650 --> 02:52.920
loop.

02:53.700 --> 02:55.800
Well, I found out years later, that is complete rubbish!

02:56.100 --> 02:59.130
It is always the end of the loop, regardless of which one you use.

03:03.410 --> 03:08.870
But there is an important difference, though. With the postfix version, that makes a copy of the

03:09.110 --> 03:10.730
variable, before incrementing it.

03:11.210 --> 03:16.580
So in your loop you would have code like this at the end. So it is going to back up the old counter and then

03:16.580 --> 03:19.880
increment the counter, and then return the old value of the counter.

03:20.880 --> 03:23.970
So it is beter to use the prefix version for loop counters.

03:25.440 --> 03:27.480
Admittedly, modern compilers are very clever.

03:27.510 --> 03:32.640
They will probably see that the temporary variable is never used, and optimize it away, but it is still

03:32.640 --> 03:34.020
better to use the prefix version.

03:37.460 --> 03:42.980
If we are writing a class that has arithmetical operators, or something that works like a pointer, if

03:42.980 --> 03:48.710
we are writing an iterator, for example, we should probably implement these operators. For the prefix

03:48.710 --> 03:49.090
version,

03:49.100 --> 03:53.030
we just do whatever we need to do to increment the members.

03:54.000 --> 03:58.290
Then we return the modified object, and we can do that by reference.

03:59.490 --> 04:01.600
And for the prefix decrement operator,

04:01.600 --> 04:03.090
that works the same way as well.

04:06.500 --> 04:08.240
For the postfix operator.

04:08.240 --> 04:11.690
We need to make a copy of the object before we modify it.

04:12.650 --> 04:16.700
Then we do the increment, and then we return the original object.

04:17.270 --> 04:19.460
So we are returning a local variable.

04:19.760 --> 04:22.370
So we do not want to do that by reference.

04:22.700 --> 04:23.750
That is a very bad idea.

04:24.140 --> 04:25.460
So we return by value.

04:25.910 --> 04:28.010
So we have two functions called "operator plus

04:28.010 --> 04:31.130
plus". One returns by reference and one returns by value.

04:31.550 --> 04:34.580
But in C++, you cannot overload on return type.

04:35.360 --> 04:39.920
So we need some way to tell the compiler, which is the prefix version and which is the postfix.

04:40.940 --> 04:46.190
And the rule is that if you put an int argument, then that is the postfix version.

04:46.640 --> 04:48.950
And if you have no arguments, that is the prefix version.

04:49.910 --> 04:53.030
So we put an int arguments here, but you do not need to use that.

04:54.200 --> 04:56.050
So let's try that out with our complex number

04:56.060 --> 04:59.060
class. We have our real and imaginary members.

04:59.660 --> 05:07.400
We have the constructor. And then we have our operators for incrementing and decrementing. The prefix version will return

05:07.400 --> 05:08.360
by reference.

05:09.020 --> 05:13.070
The postfix version returns by value, and takes an int argument.

05:13.940 --> 05:18.910
And then we have a member function to printout the members. For the prefix operator,

05:18.920 --> 05:20.900
we are adding one to the object.

05:21.350 --> 05:22.610
One is a real number.

05:23.000 --> 05:26.900
So we just add one to the real part, and we leave the imaginary part unchanged.

05:27.530 --> 05:29.480
And then we return the modified object.

05:32.480 --> 05:33.950
For the postfix operator,

05:33.950 --> 05:38.990
we copy the object before modifying, and then we return this copy.

05:40.070 --> 05:42.710
And the same for the decrement operators.

05:45.470 --> 05:48.200
In the main function, we create a complex object.

05:48.710 --> 05:49.970
Then we print out its members.

05:50.480 --> 05:52.250
We call the prefix operator.

05:54.560 --> 05:56.270
Then we call the postfix operator.

05:56.600 --> 05:58.500
This should return the original object.

05:58.520 --> 05:59.720
So we are going to check that.

05:59.720 --> 06:01.940
We are going to use that to initialize a new object.

06:03.760 --> 06:06.220
And then we do the same for the decrement operators.

06:07.780 --> 06:08.830
So let's see what happens.

06:10.710 --> 06:17.340
So there is our original object. When we increment it, the real part goes up to 6, from 5, and the imaginary

06:17.340 --> 06:18.360
part is unchanged.

06:19.380 --> 06:25.530
When we call the postfix version, the real part goes from 6 to 7, but the returned object still has

06:25.530 --> 06:26.640
a real part of 6.

06:27.600 --> 06:35.490
And similarly for the decrement. The postfix operator takes the real part from 6 to 5, but the

06:35.500 --> 06:37.890
returned object still has a member with the value 6.

06:39.060 --> 06:40.410
Okay, so that is it for this video.

06:40.800 --> 06:41.610
I will see you next time.

06:41.610 --> 06:43.800
But until then, keep coding!
