it never pass c2 to the copy constructor.
a) it pass a reference to it, if the copy constructor is defined as "Complex(Complex& refr)"
b) it pass a copy of it, if the copy constructor is defined as "Complex(Complex copy).
just dont consider references in the context of objects or copy constructors, but in the context of a simple function :
int incr1(int value) { value = value + 1; return value; }
vs
int incr2(int& value) { value = value + 1; return value; }
in incr1 value is local to the function, it is a copy of the value you pass as parameter
in incr2 it is'nt local to the function, there is no copy done.
// not tested sample :
#include <assert.h>
void main() {
int a_value = 2;
int result1 = incr1(a_value); // no reference, a copy, local to the function, is made.
assert(a_value == 2); // ok
assert(result1 == 3); // ok
int result2 = incr2(a_value); // with reference, there is no copy made.
assert(a_value == 2); // error, the original a_value parameter as been incremented.
assert(a_value == 3); // ok
assert(result2 == 3); // ok
}the incr1 is more "secure" (it is said "pure", for this and others reasons), but it always make a temporary int that is a copy of the parameter you give to it.
the incr2 is less "secure", but there is no temporary int created.
that's exactly to prevent the temporary int/Complex that copy constructors always require a reference, because when you call the copy constructor explicitly (in : Complex c3(c2); ), the copy constructor for the temporary will be called implicitly too, and the copy constructor for the temporary of the temporary called implicitly will be called implicitly too, etc.
hope this help.