Copy semantics allow us to make deep copies of objects, but in some situations,
we would get a better performance from a shallow copy instead.
Let's get back to genetic engineering.
Here I have two new subjects, a chicken and a lizard.
I want to have anzu as a subject,
but I don't have its genetic material so I just declared it as an empty object.
In case you don't know,
anzu is some kind of a dinosaur that looked like a
combination of a chicken and a lizard.
So since dinosaurs don't exist anymore,
I figured that I could combine these two subjects to make
one because that's how biology works, right?
And of course,
this will not work because we didn't define a plus
operator for the Subject class.
Let's do that now.
The subject_id of this new object will be the sum total of these two objects.
Then I will create an array of four characters,
which will replace the string literal we usually pass to create new subjects.
The genetic code of this new subject will be the
combination of sequences from both objects.
The first two bases are taken from the chicken,
and the next two are taken from the lizard.
And finally,
we can use these variables to instantiate a new
subject and return it from the function.
Notice that I made this reference constant, and now you know why.
Because in case someone decides to add more than two subjects,
this operator would still work.
The subject we returned from this operator function is a prvalue,
because it has no identity yet. It is just a new,
unassigned object.
And if we didn't make this parameter constant,
then this new operator call would not be able to accept it because
non‑constant references only accept L values.
Okay, and now this operator is finished, so let's get back to the main function.
When this expression gets evaluated,
a new subject will be created and assigned to this anzu object.
But remember that this expression alone will result in a temporary object,
which is a PR value.
When I compile this program,
the copy assignment operator will make a deep copy of this object.
To make sure that this actually happens,
I will add a special message to the copy constructor and
also to the copy assignment operator.
This way we will know when one of them is used by the program.
And now, let's compile it.
It all works as expected.
The copy assignment will make a deep copy of an object,
and anzu will have a new genetic sequence.
But why do we need a deep copy in this situation?
After all, the result of this addition is a temporary object,
which will disappear as soon as the program goes past this statement.
So why don't we just steal the sample pointer from this
prvalue object and give it to anzu,
the dinosaur? Working with temporary prvalues in this way will
improve the performance of the whole program.
To define this special behavior,
we would have to know when this assignment operator works with prvalues.
Fortunately, we learned this in the previous lesson.
To define a special behavior for temporary values,
we can overload a function, which will take in an rvalue reference.
In this case, we need to overload the assignment operator.
The definition will look similar to the copy assignment,
but instead of making a copy of this genetic code,
we will just steal a pointer to the genetic code of this temporary object.
In other words, this is just like a shallow copy.
Of course, we need to again check if this subject is assigned to itself,
and also return the object itself as a reference.
Nothing new here.
Before stealing the address from the other object,
I also need to delete the DNA object at which this sample
pointer points to because if I don't do that,
we would have a memory leak.
And finally, when we steal everything from this object,
I will completely destroy it by setting its id to 0 and its sample to a nullptr.
This is done to make sure that some other part of the program
doesn't mess with this temporary object after we steal its
pointer because we don't want to share the ownership or the DNA
object under any circumstances.
Maybe that seems unlikely in this situation,
but you will see that we can also use this operator on values with identity.
But more on that later.
The assignment operator, like this one,
which uses an rvalue reference to steal from temporary object,
is also known as a move assignment operator.
Creating a shallow copy of an object, which we then invalidate,
can be seen as moving all of the resources from one object to another.
Move assignment operator is part of the so‑called move semantics.
It is a good practice to mark this operator with noexcept
to let the other parts of the program know that this
function is resilient to exceptions.
And this is not only a good practice, I urge you to do this because if you don't,
some STL containers will not be able to use this operator properly.
But more on this later.
Now let's compile this program to see if it works.
And it does.
You can see that the move assignment operator was used
instead of the copy alternative.
We know that copy semantics assume the existence of the copy
constructor and copy assignment operator,
so to implement move semantics, we also need to create a move constructor.
I will move this expression up to the declaration of the object so that we can
immediately initialize it by the result of this combination.
This should use the constructor because this
statement does an implicit conversion.
It is actually making a call to the copy constructor.
But let's overload this constructor to make one that works with prvalues.
In other words, let's make a move constructor.
Move constructor will receive an rvalue reference,
and I will also mark it as a function which throws no exceptions.
Just like in the assignment,
we are making a shallow copy by stealing the values from all data members.
But of course,
we cannot forget to also destroy this temporary object
by invalidating all of its resources.
And that's it.
Nothing special.
If I compile this program now,
the move constructor should be used to create the anzu object,
but it isn't, and to make things worse,
copy constructor was not used either because if it was, we
would see its special message. Join me in the next lesson
to see why this happened.