Copying Reference-based Collection Classes
What happens when you make a copy of a reference-based collection class, or any class that references another object, for that matter? It depends which of the two general approaches you choose: shallow copying or deep copying.
1. A shallow copy of an object is a new object whose instance variables are identical to the old object. For example, a shallow copy of a Set has the same members as the old Set, and shares objects with the old Set through pointers. Shallow copies are sometimes said to use reference semantics.
NOTE: The copy constructors of all reference-based Rogue Wave collection classes make shallow copies.
2. A deep copy of an object is a new object with entirely new instance variables; it does not share objects with the old. For example, a deep copy of a Set not only makes a new Set, but also inserts items that are copies of the old items. In a true deep copy, this copying is done recursively. Deep copies are sometimes said to use value semantics.
Note that some reference-based collection classes have a copyContentsTo() member function that returns a new object with entirely new instance variables. This copying is not done recursively, and the new instance variables are shallow copies of the old instance variables.
Here is a graphical example of the differences between shallow and deep copies. Imagine
Bag, an unordered collection class of objects with duplicates allowed, that looks like this before a copy:
Making a shallow copy and a deep copy of
Bag would produce the following results:
You can see that the deep copy copies not only the bag itself, but recursively all objects within it.
The copying approach you choose is important. For example, shallow copies can be useful and fast, because less copying is done, but you must be careful because two collections now reference the same object. If you delete all the items in one collection, you will leave the other collection pointing into nonsense.
You also need to consider the approach when writing an object to disk. If an object includes two or more pointers or references to the same object, it is important to preserve this
morphology when the object is restored. Classes that inherit from
RWCollectable inherit algorithms that guarantee to preserve an object's morphology. You'll see more on this in
Chapter 8.