
Samuel Y. answered 07/12/20
Undergrad Student in University of California pursuing B.S. in CS.
My understanding of the Rule of Three is that it emphasizes on an object being a "shallow" copy or a "deep" copy. The Rule of Three touches on Destructors, Copy Constructors, and Copy Assignment Operator. What are "shallow" copies vs "deep" copies?
Think of a video game and creating a copy of a character from an existing character. Let's say there is an existing character named Samuel and you want to make a copy of the attributes named Sammy. The attributes could be health, strength, inventory. Without overloading any operators or creating copy constructors, you just create a character object named Sammy and say Sammy = Samuel. Simple enough, right?
What actually happened was that you made a shallow copy. A shallow copy clones every attribute which you might not actually have intended. Let's say the inventory attribute is a pointer which points to a memory address. Because you copied the exact same ADDRESS to Sammy, when you open Sammy's inventory he will actually have access to Samuel's inventory. This is the issue with SHALLOW copies. This is situational as sometimes you would like an object to have the same pointer as another object, but for the most part I'd rather each copy I make to be a DEEP copy.
In the situation of a DEEP copy, Sammy's inventory initially owns the same items as Samuel's items, but when Sammy picks up an item it will not be added to Samuel's inventory. With proper overloading and creation of a copy constructor, Sammy will have a unique inventory to himself as opposed to just accessing Samuel's inventory.
So to avoid this situation, what you need to do is to think of the Rule of Threes. The programmer should define Copy Constructors, Copy Assignment, and Destructors. Why is the destructor? If one were to make a shallow copy and destroy it later on, it would be running the destructor twice. A shallow copy will copy the destructor along with having it's own destructor, and will try to destroy its values twice, which isn't good.The values don't exist after the first destruction, so when the second destructor is called, the program will most likely crash.
How about the Copy Constructor? You should be explicitly defining the copy constructor in order to allocate memory for new values, otherwise the copy object will have access to the same memory addresses via pointers and arrays(which are just dressed up pointers, really).
Copy Assignment? In C++, the programmer has the ability to overload/change how standard operators behave (+, -, *, /, =, etc). We're specifically looking at overloading the equals = operator in this instance. You will want to implement a copy constructor and destructor in this overload to tie this all up together!