WEBVTT

00:00:00.440 --> 00:00:01.850
It's time for the summary.

00:00:02.240 --> 00:00:05.760
If we want to access the objects data member through a pointer,

00:00:05.770 --> 00:00:08.600
we need to first dereference that pointer to use the dot

00:00:08.600 --> 00:00:12.380
operator, because dot operator cannot be used on the pointer

00:00:12.380 --> 00:00:15.610
itself. But there is a cleaner way to do this.

00:00:15.620 --> 00:00:18.170
We can instead use the member of pointer operator,

00:00:18.170 --> 00:00:20.560
also known as the arrow operator.

00:00:20.940 --> 00:00:25.460
Arrow operator will dereference the pointer and then access the objects member.

00:00:26.440 --> 00:00:30.340
We also discussed runtime polymorphism when working with class

00:00:30.340 --> 00:00:35.120
inheritance. Pointer to the base class can be used as an interface

00:00:35.120 --> 00:00:39.890
for derived classes, but since we are pointing to the derived class

00:00:39.890 --> 00:00:41.670
with the base class pointer,

00:00:41.680 --> 00:00:45.760
we can only access the member functions that belong to the base class.

00:00:46.540 --> 00:00:51.820
However, we can fix this by late binding the overridden functions at runtime.

00:00:51.830 --> 00:00:56.760
All we need to do is make the member function from the base class virtual.

00:00:57.140 --> 00:01:00.970
And now, every derived class will have an additional virtual

00:01:00.970 --> 00:01:03.560
pointer inherited from the base class.

00:01:03.940 --> 00:01:06.980
This virtual pointer points to the virtual table, which

00:01:06.980 --> 00:01:09.530
helps the compiler bind the correct function to the

00:01:09.530 --> 00:01:11.950
correct type of object at runtime.

00:01:12.740 --> 00:01:14.730
Whenever you work with virtual functions,

00:01:14.730 --> 00:01:18.070
you also need to make the destructor virtual to prevent potential

00:01:18.070 --> 00:01:21.960
memory leaks. When the resource is too large,

00:01:21.970 --> 00:01:24.340
we need to allocate it on the heap.

00:01:24.350 --> 00:01:28.550
This forces us to use pointers as data members to point to these

00:01:28.560 --> 00:01:33.240
allocated resources, and that is where the concept of RAII comes

00:01:33.240 --> 00:01:37.260
in. We need to take care of those resources once the object goes

00:01:37.260 --> 00:01:39.070
out of scope. To do this,

00:01:39.070 --> 00:01:41.550
we can use the delete operator inside of the class's

00:01:41.550 --> 00:01:44.560
destructor to deallocate resources from the heap.

00:01:45.440 --> 00:01:46.070
However,

00:01:46.080 --> 00:01:50.550
if we try to assign one object instantiated from this class to another

00:01:50.550 --> 00:01:55.390
one, things get complicated. Copy assignment operator and copy

00:01:55.390 --> 00:01:59.050
constructor make shallow copies, which means that they only copy the

00:01:59.050 --> 00:02:02.160
pointer's address but not the resource itself.

00:02:02.740 --> 00:02:07.620
We need to redefine these copy semantics to allocate new resources.

00:02:07.630 --> 00:02:10.750
We need to make a deep copy instead of a shallow one.

00:02:11.840 --> 00:02:16.020
But sometimes, deep copies are just an overkill, because we are

00:02:16.020 --> 00:02:19.970
working with temporary values. To improve performance, we can

00:02:19.980 --> 00:02:23.760
implement move semantics, which will steal the resources from

00:02:23.760 --> 00:02:26.460
another object instead of making a copy.

00:02:26.840 --> 00:02:31.230
Move constructor and move assignment operator will also invalidate

00:02:31.230 --> 00:02:34.360
the object that was relinquished of its resources.

00:02:34.740 --> 00:02:38.210
We can use rvalue references to overload the copy

00:02:38.210 --> 00:02:41.880
constructor, and then all of the temporary values will be

00:02:41.880 --> 00:02:44.250
sent to the move constructor instead.

00:02:45.540 --> 00:02:49.430
Prvalue is the value category that represents temporary values

00:02:49.430 --> 00:02:54.250
without an identity, like integer literals, for example. Lvalue

00:02:54.250 --> 00:02:56.390
is the value that has an identity.

00:02:56.400 --> 00:02:57.900
This can be a variable,

00:02:57.910 --> 00:03:02.160
a pointer, a reference, or anything else that has a fixed place in memory.

00:03:03.240 --> 00:03:06.430
We can use std::move function to return an rvalue

00:03:06.430 --> 00:03:08.760
reference to the functions argument.

00:03:09.640 --> 00:03:14.720
This will turn that value into an xvalue, expired value that has an

00:03:14.720 --> 00:03:20.000
identity but it is also movable. Glvalue is a super category that

00:03:20.000 --> 00:03:25.460
represents values with an identity, and lvalue belongs to the glvalue

00:03:25.460 --> 00:03:32.110
category. Rvalues are movable values, so prvalues are also rvalues,

00:03:32.120 --> 00:03:38.030
but xvalues are both rvalues and glvalues, because they are movable and they

00:03:38.030 --> 00:03:42.320
can have an identity. And, we are done with this module.

00:03:42.330 --> 00:03:43.680
If you have any questions,

00:03:43.690 --> 00:03:46.960
ask them in the discussion. I will see you in the next one,

00:03:46.960 --> 00:03:51.040
where we will go over modern C++ ways of handling all of the

00:03:51.040 --> 00:03:52.860
things we covered until now.

00:03:53.240 --> 00:03:54.350
Thank you for watching.
