If that were Java at least, the second line is just making a new reference to the original
object. So original
and shallowCopy
would point to the exact same object (no copy is made at all). I am guessing that this is C++ which may have different semantics, though I would be surprised if that second line created a new object.
Let me create an artificial case to help explain the difference between a shallow copy and a deep copy. Suppose we have the following two classes:
class Toy {
private static int nextId = 0;
private final int id;
Toy() {
this.id = nextId++;
}
}
class ToyBox {
private final List<Toy> toys = new ArrayList<>();
public void addToy(Toy toy) { toys.add(toy); }
}
And let us make a couple of Toy
objects and put them into the ToyBox
:
class Main {
public static void main(String[] args) {
var toyBox = new ToyBox();
var toy0 = new Toy();
toyBox.addToy(toy0);
var toy1 = new Toy();
toyBox.addToy(toy1);
}
}
So we have three objects in total: one ToyBox
and two Toy
objects.
Now, if we make a shallow copy of the ToyBox
it will create a new ToyBox
object, but that ToyBox
would contain references to the existing Toy
objects. This is the exact behavior that the clone()
method has in Java. So writing that out:
class ToxBox implements Cloneable {
... // existing implementation
public ToyBox shallowClone() {
return super.clone();
}
}
class Main {
public static void main(String[] args) {
... // existing implementation
var shallowClone = toyBox.shallowClone();
}
}
If we want a deep copy, we have to make a copy of each Toy
inside the ToyBox
as well:
class Toy implements Cloneable {
... // existing implementation
}
class ToyBox implements Cloneable {
... // existing implementation
@Override
public ToyBox clone() {
var clone = shallowClone();
clone.toys.clear();
for (var toy : this.toys) {
clone.addToy(toy.clone());
}
return clone;
}
}
class Main {
public static void main(String[] args) {
var toyBox = new ToyBox();
var toy0 = new Toy();
toyBox.addToy(toy0);
var toy1 = new Toy();
toyBox.addToy(toy1);
var shallowClone = toyBox.shallowClone();
var deepClone = toyBox.clone();
}
}
I reproduced the full main
method so that we can run through the whole state of affairs. After this code executes, there will be 3 ToyBox
objects and 4 Toy
objects. The toyBox
has two toys (toy0
and toy1
). Since shallowClone
is a shallow copy of toyBox
it is a distinct object (ie. toyBox != shallowCopy
), but it has the exact same toys (toy0
and toy1
). Finally, deepClone
is a deep copy of toyBox
so it is a distinct object (toyBox != deepClone
) and has two newly created toys that are clones of toy0
and toy1
(we will call them toy0Clone
and toy1Clone
). So toy0 != toy0Clone
and toy1 != toy1Clone
.
NOTE: If the Toy
class had references to other objects, we would have to recursively make deep copies all the way down to the bottom until we had only primitive types.
Hopefully that helps clarify the difference between a deep copy and a shallow copy for you.