As the name suggests, a copy constructor is called whenever an object is copied. This happens in the following cases:
Whenever an object copying scenario like the ones above is encountered, the copy constructor is invoked. A copy constructor can be either user defined or compiler defined. If the user does not define a copy constructor, then the default compiler defined copy constructor will be invoked during object copy scenarios. The default copy constructor is a bit-by-bit (member wise) copy. But often you will encounter situations where this is not desirable since this is just a shallow copy and sometimes you do not want an exact copy or you may want to do some custom resource management.
Class t1;
Class t2=t1; // Copy Constructor is invoked
Class t3;
t3=t1; // Assignment Operator is invoked
In the Code snippet above, the constructor is invoked twice, during the creation of objects t1 and t3. (Creation of t2 invokes the copy constructor). The destructor is invoked 3 times though. In cases like these, if the constructor allocates memory and the destructor frees it, you will see the t2's destructor will try to delete already deleted memory, if t1 is destroyed before t2 or vice-versa. Meaning, you are hosed. To prevent this, a user defined copy constructor needs to be provided. which doesn't do a simple bit-by-bit but rather assigns memory specifically for the object and does a deep copy if required.
To define a copy constructor for a class T, a constructor of the following format needs to be defined.
Class T
{
…
T(const T& t)
…
}
You need a reference because if it were T(T t), it would end in a infinite recursion. (Was that an oxymoron?). const because you are not changing the object in the constructor, you are just copying its contents
Some Rules of Thumb: