If I have a game j2 here, which is a copy of j1,
it will have a copy of the vector of characters,
but if we only make a surface copy,
if we only use the default copy constructor,
then we will copy pointers.
We will simply copy the various elements one after the other,
copying only the pointers.
This means that the game j2 will point to
the same characters as the game j1.
And this is usually undesirable, since we generally want
both collections to have independent elements.
Here in the example of the games,
we would like to be able to play the first and second games separately,
without the characters from one game influencing the characters from the other.
This problem does not occur with unique pointers
since with unique pointers,
it is impossible to have multiple pointers
to the same characters,
and we would not be allowed to copy them.
So copying is inherently forbidden
with a game containing unique pointers.
The compiler would indeed have forbidden this call to the copy constructor,
which tries to makes copies of the unique pointers.
So the program would have realized that there was a problem here.
Moreover, with C-style pointers, it is important not to forget deallocation
and especially the golden rule,
that whoever allocates the memory, whoever calls "new",
must also free the memory, that is, call "delete".
Here is a reminder of how this worked;
to add a character to the game, the character was created
with a call to "new", so for example "new Magicien",
with parameters for its constructor.
So it is this one who makes this call here, who will have to handle destruction.
In this case, there is no way of getting the pointer that was allocated,
since this value wasn't saved,
and we must provide a means to destroy the characters
we have put into our collection.
For example, with a "detruire_personnage" method (TN: means "destroy_character")
where we would indicate the address of the character we wish to
destroy; but this would suppose of course that the one making the allocation
keeps a trace of their pointers to be able to use them here.
We could also destroy a character by indicating which number,
which index that character has,
supposing that we had numbered, that we had access to the characters' numbers,
we could destroy character number 2, etc.
Or, we could provide a method that would destroy all the characters.
That is up to you, depending on your design, depending
on the heterogeneous container that you want to use.
But in any case, you will have to think about
providing methods allowing deallocation of allocated memory,
to be able to free the pointers that are in your container.