| > Correct me if I'm wrong: In int main, "complex c3(c2)" creates a copy of c2 and thus passes c2 to copy constructor. 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. |
int incr2(int& value) { value = value + 1; return value; }
is the same as
int incr3(int* value) { (*value) = (*value) + 1; return *value; }
and they will be used diferently for the same result :
void main() {
}in the call to incr3 "&a_value" can be read : address_of "a_value".
and in the body of incr3 "*value" can be read : content of address "value".
and finnaly in the prototype "int incr3(int* value)", "int*" can be read : pointer to an int, or address of an int.
pointer/address are a fundamental concept for programming at large, the concept of "indirection".
all this may seem unrelated at first, but in your Complex problem, you can try something like :
#include <iostream>
...
Complex c2;
std::cout << &c2 /* address of c2 */ << std::endl;
and in your copy constructor :
Complex(Complex& c) {
}you will see that, with a reference, the addresses are the sames, but without references you will get different addresses meaning that your variables are'nt the same (in the case of function parameters/arguments they are copies of the parameters values, that's why we call this "pass by value" semantic, rather than "pass by reference" or "pass by address" or box, or indirection, or whatever having the same meaning).
hope this help.