If we pass the copy constructor the argument by value, its copy would get constructed using the copy constructor. This means the copy constructor would call itself to make this copy. This process would go on and on until the compiler runs out of memory.
This can be explained with the help of following example:
sample (sample p)
i = p.i;
void main( )
While executing the statement sample s1 ( s ), the copy constructor would get called. As the copy construct here accepts a value, the value of s would be passed which would get collected in p. We can think of this statement as sample p = s. Here p is getting created and initialized. Means again the copy constructor would get called. This would result into recursive calls.Hence we must use a reference as an argument in a copy constructor.