Copy operations are distinguished by how they treat pointers:
In a shallow copy, all pointers are copied.
Leads to shared data on the heap.
In a deep copy, objects pointed to are copied, then the new pointer set to the address of the copied object.
Copied objects keep exclusive access to the things they point to.
This was a shallow copy:
This was a deep copy:
In this example, deep is preferred. That's not always the case. When we design an ADT we have to decide whether the things it points to are things we want to share with other objects or whether we want to own them exclusively. That's a matter of just how we want our ADTs to behave, which depends in turn on what we expect to do with them.
In this context, it should be noted that “shallow” and “deep” are actually two extremes of a range of possible copy depths - sometimes our ADTs call for a behavior that has us treat some pointers shallowly and others deeply.