C++/copy constructor
Expert: Joseph Moore - 9/29/2009
QuestionHi ,
I want to know as when we have to use the copy constructor in the program code ..
Thanks
Srikanth
AnswerHi, Srikanth.
You need to create a copy constructor when your class uses dynamic memory. The default copy constructor does what is known as a shallow copy. A shallow copy simply takes every item in the new instance of your class and sets it equal to every item in the old instance of the class. It's just like doing a whole bunch of assignment operators:
myInt = oldInstance.myInt;
The reason this doesn't work when a class contains dynamic memory is simple: assigning one pointer to another makes each pointer point to the same block of memory. Thus, if you have dynamically allocated an object or an array in a class, then instead of making a copy of said object or array, both instances of your class will point to the same object or array. When the original instance of your class is destroyed, generally any memory it has allocated will be destroyed along with it, meaning your new instance will point to invalid data. Consider something like this:
class myClass
{
public:
myClass() { myIntArray = new int[50]; }
~myClass() { delete [] myIntArray; }
private:
int* myIntArray;
};
void main()
{
myClass firstInstance;
myClass secondInstance(firstInstance);
}
Here, the firstInstance object creates the dynamic array. The secondInstance object uses the default copy constructor and winds up pointing to the same block of memory instead of allocating its own block of memory and copying the contents over. At first blush, this particular example may not even seem all that bad, because we aren't even doing anything with the objects we create. However, even this simple demonstration program ends up crashing because a delete command is called twice on the same block of memory. Program execution goes something like:
constructor
copy constructor
destructor
destructor
This means that the "delete [] myIntArray;" code is called twice on the same memory address.
When you create a copy constructor, generally you force it to do what is known as a deep copy. A deep copy, instead of simply calling the assignment operator on every item, will actually allocate memory where it needs to and copy the data from the original instance into the new instance. For the simple program above, the copy constructor would be:
myClass(const myClass& rhs)
{
myIntArray = new int[50];
memcpy(myIntArray, rhs.myIntArray, sizeof(int) * 50);
}
You can see how it allocates a duplicate set of memory and copies the contents from the original into the new. Now, granted, this example is a bit dumb (thanks to the hard-coded "50" in there), but it demonstrates the concept, anyway.
I hope this clears everything up for you. If you have any further questions, please do not hesitate to ask. I'm here to help. :)